多态
指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
多态提高了程序的可扩展性和可维护性
多态的实现必须有三个条件
- 必须要有继承
- 必须要有重写
- 父类引用指向子类对象
class Animal {
name: string
constructor(name: string) {
this.name = name
}
run(distance: number = 0) {
console.log(`${this.name}跑了 ${distance}m`)
}
}
class Dog extends Animal {
constructor(name: string) {
// 调用父类型构造方法
super(name)
}
// 重写父类型的方法
run(distance: number = 100) {
console.log('dog...')
super.run(distance)
}
cat() {
console.log("哈哈哈")
}
}
class Cat extends Animal {
constructor(name: string) {
// 调用父类型构造方法
super(name)
}
// 重写父类型的方法
run(distance: number = 10) {
console.log('cat...')
super.run(distance)
}
}
// 父类型引用指向子类型的实例 ==> 多态
let small: Animal = new Dog('小奶狗');
small.run();
small = new Cat("小猫咪")
small.run();
修饰符
默认为 public
在 TypeScript 里,成员都默认为 public
。
class Animal {
age: Number
public name: string
constructor(name: string, age:Number) {
this.name = name;
this.age = age
}
}
const an = new Animal('zhangsan', 28)
console.log(an.name, an.age);
输出:
zhangsan 28
private
当成员被标记成 private
时,它就不能在声明它的类的外部访问
class Animal {
age: Number
public name: string
constructor(name: string,age:Number) {
this.name = name;
this.age = age
}
}
const an = new Animal('zhangsan', 28)
console.log(an.name, an.age);
编译出错:
属性“age”为私有属性,只能在类“Animal”中访问
一般属性为private时,给外部提供get、set方法来操作该属性
class Animal {
private age: Number;
public name: string;
constructor(name: string, age: Number) {
this.name = name;
this.age = age;
}
getAge():Number {
return this.age;
}
setAge(age: Number):void {
this.age = age;
}
}
const dog: Animal = new Animal('zhangsan', 28)
console.log(dog.getAge());
dog.setAge(12);
console.log(dog.getAge());
out
28
12
protected
protected
修饰符与 private
修饰符的行为很相似,但有一点不同,protected
成员在子类中仍然可以访问。
class Animal {
private age: Number;
public name: string;
protected gender: string;
constructor(name: string, age: Number, gender: string) {
this.name = name;
this.age = age;
this.gender = gender
}
}
class Dog extends Animal {
constructor(name: string, age: Number, gender: string) {
super(name, age, gender)
}
eat() {
console.log("一个名叫" + this.name + "小狗,居然是" + this.gender + "的,简直不敢相信.")
}
}
const dog: Dog = new Dog('zhangsan', 28, '女')
dog.eat();
out
一个名叫zhangsan小狗,居然是女的,简直不敢相信.
总结
- public:公有,不加修饰符默认公有。类里、子类、外部可以访问
- protected:保护类型,类里、子类可以访问,类外不可访问
- private:类里可以访问,子类、外部不可访问