基本使用
(() => {
class Person {
// 定义属性
name: string
age: number
// 构造方法,实例化对象的时候,直接对属性的值进行初始化
constructor(name: string = '张三', age: number = 18) {
// 更新对象中的属性数据
this.name = name
this.age = age
}
// 实例方法
sayHi(message: string): string {
return '大家好,我叫' + this.name + '我今年' + this.age + '岁了,我对大家说:' + message
}
}
// 创建类的实例,使用默认属性
const person1 = new Person()
// 调用实例的方法
console.log(person1.sayHi('你好啊'))
// 创建类的实例,使用自定义属性
const person2 = new Person('李四', 20)
// 调用实例的方法
console.log(person2.sayHi('hello'))
})()
// 输出结果
// 大家好,我叫张三我今年18岁了,我对大家说:你好啊
// 大家好,我叫李四我今年20岁了,我对大家说:hello
继承
(() => {
// 定义一个父类(超类)
class Person {
// 定义属性
name: string
age: number
// 构造方法,实例化对象的时候,直接对属性的值进行初始化
constructor(name: string, age: number) {
// 更新对象中的属性数据
this.name = name
this.age = age
}
// 实例方法
sayHi(message: string): string {
return '大家好,我叫' + this.name + '我今年' + this.age + '岁了,我对大家说:' + message
}
}
// 定义一个子类(派生类)
class Student extends Person {
// 调用父类中的构造函数
constructor(name: string, age: number) {
super(name,age);
}
// 继承父类中的方法
sayHi(message: string): string {
return super.sayHi(message);
}
}
// 创建类的实例,使用自定义属性
const student = new Student('李四', 20)
// 调用实例的方法
console.log(student.sayHi('hello'))
})()
// 输出结果
// 大家好,我叫李四我今年20岁了,我对大家说:hello
多态
父类型的引用指向了子类型的对象,不同类型的对象针对相同的方法产生了不同的行为
(() => {
// 定义一个父类(超类)
class Person {
// 定义属性
name: string
// 构造方法,实例化对象的时候,直接对属性的值进行初始化
constructor(name: string) {
// 跟鞋对象中的属性数据
this.name = name
}
// 实例方法
run(num: number = 0): string {
return '大家好,我叫' + this.name + '我跑了' + num + '米'
}
}
// 定义第一个子类(派生类)
class Student extends Person {
// 调用父类中的构造函数
constructor(name: string) {
super(name);
}
// 重写父类中的方法
run(num: number = 5): string {
return '大家好,我叫' + this.name + '我跑了' + num + '米'
}
}
// 定义第二个子类(派生类)
class Teacher extends Person {
// 调用父类中的构造函数
constructor(name: string) {
super(name);
}
// 重写父类中的方法
run(num: number = 10): string {
return '大家好,我叫' + this.name + '我跑了' + num + '米'
}
}
// 创建父类的实例
const person1: Person = new Person('张三')
// 调用实例的方法
console.log(person1.run())
// 创建子类1的对象
const student1 = new Student('李四')
console.log(student1.run())
// 创建子类2的对象
const teacher1 = new Teacher('王五')
console.log(teacher1.run())
// 创建父类的实例
const person2: Person = new Person('张三')
// 调用实例的方法
console.log(person2.run())
// 使用父类型创建子类1的对象
const student2: Person = new Student('李四')
console.log(student2.run())
// 创建使用父类型创建子类2的对象
const teacher2: Person = new Teacher('王五')
console.log(teacher2.run())
// 定义函数,该函数需要传入参数是Person类型的
function showRun(per: Person):void{
console.log(per.run())
}
showRun(person2)
showRun(student2)
showRun(teacher2)
})()
// 输出结果
// 大家好,我叫张三我跑了0米
// 大家好,我叫李四我跑了5米
// 大家好,我叫王五我跑了10米
// 大家好,我叫张三我跑了0米
// 大家好,我叫李四我跑了5米
// 大家好,我叫王五我跑了10米
// 大家好,我叫张三我跑了0米
// 大家好,我叫李四我跑了5米
// 大家好,我叫王五我跑了10米
修饰符
主要用于描述类中的成员(属性,构造函数,方法)的可访问性,默认是pubile,公共的,任何位置都可以访问类中的成员
public (默认值, 公开的外部也可以访问)
(() => {
// 定义一个父类(超类)
class Person {
// 定义属性
public name: string
// 构造方法,实例化对象的时候,直接对属性的值进行初始化
public constructor(name: string) {
// 更新对象中的属性数据
this.name = name
}
// 实例方法
public run(num: number = 0): string {
return '大家好,我叫' + this.name + '我跑了' + num + '米'
}
}
})()
// 创建父类的实例
const person1: Person = new Person('张三')
// 类的外部访问类中的成员属性
console.log(person1.name)
// 类的外部访问类中的成员方法
console.log(person1.run())
// 执行结果
// 张三
// 大家好,我叫张三我跑了0米
private(只能类内部可以访问,子类也无法访问)
(() => {
// 定义一个父类(超类)
class Person {
// 定义属性
private name: string
// 构造方法,实例化对象的时候,直接对属性的值进行初始化
private constructor(name: string) {
// 更新对象中的属性数据
this.name = name
}
// 实例方法
private run(num: number = 0): string {
return '大家好,我叫' + this.name + '我跑了' + num + '米'
}
}
// 定义第一个子类(派生类)
class Student extends Person {
// 调用父类中的构造函数
constructor(name: string) {
super(name);
}
// 重写父类中的方法
run(num: number = 5): string {
return '大家好,我叫' + this.name + '我跑了' + num + '米'
}
}
// 创建父类的实例
const person1: Person = new Person('张三')
// 类的外部访问类中的成员属性
console.log(person1.name)
// 类的外部访问类中的成员方法
console.log(person1.run())
// 创建子类1的对象
const student = new Student('李四')
console.log(student.run())
})()
one.ts(20,9): error TS2415: Class 'Student' incorrectly extends base class 'Person'.
Property 'run' is private in type 'Person' but not in type 'Student'.
one.ts(20,25): error TS2675: Cannot extend a class 'Person'. Class constructor is marked as private.
one.ts(28,30): error TS2341: Property 'name' is private and only accessible within class 'Person'.
one.ts(32,27): error TS2673: Constructor of class 'Person' is private and only accessible within the class declaration.
one.ts(34,23): error TS2341: Property 'name' is private and only accessible within class 'Person'.
one.ts(36,23): error TS2341: Property 'run' is private and only accessible within class 'Person'.
-
protected(类内部和子类可以访问)
(() => {
// 定义一个父类(超类)
class Person {
// 定义属性
protected name: string
// 构造方法,实例化对象的时候,直接对属性的值进行初始化
protected constructor(name: string) {
// 更新对象中的属性数据
this.name = name
}
// 实例方法
protected run(num: number = 0): string {
return '大家好,我叫' + this.name + '我跑了' + num + '米'
}
}
// 定义第一个子类(派生类)
class Student extends Person {
// 调用父类中的构造函数
constructor(name: string) {
super(name);
}
// 重写父类中的方法
run(num: number = 5): string {
return '大家好,我叫' + this.name + '我跑了' + num + '米'
}
}
// 创建父类的实例
const person1: Person = new Person('张三')
// 类的外部访问类中的成员属性
console.log(person1.name)
// 类的外部访问类中的成员方法
console.log(person1.run())
// 创建子类的对象
const student = new Student('李四')
console.log(student.run())
})()
// 输出结果
// one.ts(32,27): error TS2674: Constructor of class 'Person' is protected and only accessible within the class declaration.
// one.ts(34,23): error TS2445: Property 'name' is protected and only accessible within class 'Person' and its subclasses.
// one.ts(36,23): error TS2445: Property 'run' is protected and only accessible within class 'Person' and its subclasses.
-
readonly
readonly关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。外部不能修改属性值,内部普通方法也不能修改,只能在创建对象初始化时,指定属性的值
(() => {
// 定义一个父类(超类)
class Person {
// 定义属性
readonly name: string
// 构造方法,实例化对象的时候,直接对属性的值进行初始化
constructor(name: string) {
// 更新对象中的属性数据
this.name = name
}
// 实例方法
run(): string {
// 类内部方法修改成员属性
return this.name = 'abc'
}
}
// 创建父类的实例
const person1: Person = new Person('张三')
// 类的外部访问类中的成员属性
console.log(person1.name)
// 修改实例的属性
person1.name = '李四'
console.log(person1.name)
})()
// 输出结果
// one.ts(14,19): error TS2540: Cannot assign to 'name' because it is a read-only property.
// one.ts(22,11): error TS2540: Cannot assign to 'name' because it is a read-only property.
存取器
通过
getters/setters
来截取对对象成员的访问。用于控制对对象成员的访问。
(() => {
// 外部可以传入姓氏和名字,使用set和get控制姓名数据,外部可以访问和修改
class Person{
firstName:string // 姓
lastName:string // 名
constructor(firstName:string,lastName:string) {
this.firstName = firstName
this.lastName = lastName
}
// 读取器——负责数据读取
get fullName(){
return this.firstName + '-' + this.lastName
}
// 设置器——负责数据的修改
set fullName(val){
let names = val.split('-')
this.firstName = names[0]
this.lastName = names[1]
}
}
// 实例化对象
const person:Person = new Person('东方','不败')
// 获取对象的成员属性
console.log(person.fullName)
// 设置属性的数据
person.fullName = '诸葛-孔明'
console.log(person.fullName)
})()
// 输出结果
// 东方-不败
// 诸葛-孔明
静态属性与方法
通过static修饰的属性和方法,在使用时直接通过类名.的方式调用
/*
静态属性, 是类对象的属性
非静态属性, 是类的实例对象的属性
*/
(() => {
// 定义一个类
class Person{
// 定义一个静态属性。类中默认有一个内置的name静态属性,不能冲突
static names:string = '张三'
// 定义一个静态方法
static sayHi(){
console.log('Hi')
}
}
// 调用类的静态属性
console.log(Person.names)
// 设置类的静态属性值
Person.names = '李四'
console.log(Person.names)
// 调用类的静态方法
Person.sayHi()
})()
// 输出结果
// 张三
// 李四
// Hi
抽象类
抽象类做为其它派生类的基类使用。 它们不能被实例化。不同于接口,抽象类可以包含成员的实现细节。
abstract
关键字是用于定义抽象类和在抽象类内部定义抽象方法
/*
抽象类
不能创建实例对象, 只有实现类才能创建实例
可以包含未实现的抽象方法
*/
(() => {
// 定义一个抽象父类
abstract class Person{
// 定义一个抽象方法(抽象类中只定义,不能有具体的实现)
abstract run()
// 定义一个实例方法
sayHi(){
console.log('Hi')
}
}
// 定义一个子类(派生类)
class Student extends Person{
// 重新实现抽象类中的方法,此时这个方法就是当前Person类的实例方法
run(){
console.log('整齐的跑')
}
}
// 实例化student对象
const student:Student = new Student()
student.sayHi()
// 调用抽象类中的实例方法
student.run()
})()
// 输出结果
// Hi
// 整齐的跑