1、接口(interface
)
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。
a、接口属性
// 接口interface
// 1、属性接口
interface full_name {
firstName: string;
secondName: string;
}
// 对批量参数的类型约束
function log_name(name:full_name): void {
console.log(`${name.firstName}&${name.secondName}`);
}
//直接传参的时候传入的对象的格式需要严格满足接口的规范
log_name({firstName:'tom',secondName:'jerry'}) //tom&jerry
let obj = {
firstName: "tom",
secondName: "jerry",
age:12
};
//传入一个包装的对象的话,必须包含接口所要求的字段即可
log_name(obj);
b、接口的可选属性
interface full_name {
firstName: string;
//这样表示secondName可传可不传
secondName ?: string;
}
function log_name(name: full_name): void {
console.log(`${name.firstName}&${name.secondName}`);
}
log_name({ firstName: "tom"}); //tom&undefined
c、函数类型接口
//函数类型接口对方法传入的参数,以及返回值进行约束
interface func {
(key:string,value:string):string
}
let md:func = function(key,value){
return `${key}${value}`
}
console.log(md('张三','李四')); //张三李四
d、可索引接口
//可索引接口 :对数组和对象的约束(不常用)
interface arr_obj {
[index:number]:string
}
let arr:arr_obj = ['hello','world']
//取值的时候索引为number类型,数组元素是string类型
console.log(arr[0]); //hello
e、类类型接口
//类类型接口和抽象类有点像,也是一种规范
interface Animal {
name: string;
eat(str: string): void;
}
//这里用的是 implements ,继承使用的是extends
class Dog implements Animal{
name:string
constructor(name:string){
this.name = name
}
//你可以不给eat传递参数,但是要实现eat方法
eat(){
console.log(`${this.name}爱吃肉`);
}
}
let dog = new Dog('小狗')
dog.eat()
f、接口的扩展
//接口的扩展
interface Animal{
eat():void
}
interface Dog extends Animal{
work():void
}
class middle_dog {
name:string
constructor(name:string){
this.name = name
}
coding():void{
console.log(`${this.name}在敲代码`);
}
}
//可以在实现类的继承的同时进行类类型接口
class dog extends middle_dog implements Dog{
constructor(name:string){
super(name)
}
eat():void{
console.log(`${this.name}吃吃吃`);
}
work():void{
console.log(`${this.name}在搬砖`);
}
}
let d1 = new dog('小狗')
d1.eat()
d1.work()
d1.coding()
//小狗吃吃吃
//小狗在搬砖
//小狗在敲代码
2、类(class
)
a、类的声明
// 类的声明
class Person {
name: string;
constructor(name: string) {
this.name = name;
};
getName(): string {
return this.name
}
setName(name:string) {
this.name = name
}
}
let tom = new Person('tom')
console.log(tom.getName()); //tom
tom.setName('Jerry');
console.log(tom.getName()); //Jerry
b、类的继承
// 类的继承 extends 、super
class Person {
name: string;
constructor(name: string) {
this.name = name;
};
run():string{
return `${this.name}在运动`
}
}
let p = new Person('张三')
console.log(p.run()); //张三在运动
class Student extends Person{
constructor(name:string){
super(name)
}
work():string{
return `${this.name}在工作`
}
//子类如果有与父类相同的方法,会覆盖父类的方法
}
let s = new Student('李四')
console.log(s.run()); //李四在运动
console.log(s.work()); //李四在工作
c、类的修饰符
//public 公有属性,在类里面、子类中、类外面都能访问
//protected 保护类型,在类里面、子类中可以访问
//private 私有属性,只能在类里面访问
//属性修饰符
class Person {
name: string;
protected age: number;
private sex: string;
constructor(name: string, age: number, sex: string) {
this.name = name;
this.age = age;
this.sex = sex;
}
run(): string {
return `${this.name}在运动${this.age}${this.sex}`;
}
}
let p = new Person("张三", 23, "男");
console.log(p.run());
console.log(p.name);
console.log(p.age);
console.log(p.sex);
class Student extends Person {
constructor(name: string, age: number,sex: string) {
super(name,age,sex);
}
// 子类自己的方法
work(): string {
return `${this.name}在工作${this.age}${this.sex}`;
}
}
let s = new Student("李四", 13,'女');
console.log(s.run());
console.log(s.work());
console.log(s.name);
console.log(s.age);
console.log(s.sex);
从下图中可以看到属性修饰符的不同作用
d、类的静态属性和静态方法
class Person {
name: string;
// 静态属性
static age:number
constructor(name: string,) {
this.name = name;
};
// 实例方法
getName(): string {
return this.name
}
setName(name:string) {
this.name = name
}
// 静态方法方法中只能调用静态属性
static sayHello():string{
//return `静态方法调用不了声明的属性${this.name}`
return `静态方法调用不了声明的属性${this.age}`
}
}
let tom = new Person('tom')
console.log(tom.getName()); //tom
tom.setName('Jerry');
console.log(tom.getName()); //Jerry
// 实例对象调用静态方法和静态属性会报错
// console.log(tom.sayHello());
// tom.age = 12
// console.log(tom.age);
Person.age = 12
console.log(Person.sayHello());
console.log(Person.age);
e、多态:父类定义一个基础方法,让继承的每个子类实现不同的功能
class Animal {
name:string;
constructor(name:string){
this.name = name
}
eat(){
console.log(`吃的方法`);
}
}
class Dog extends Animal{
constructor(name:string){
super(name)
}
eat(){
return this.name + `吃肉`
}
}
class Cat extends Animal{
constructor(name:string){
super(name)
}
eat(){
return this.name + `吃鱼`
}
}
f、抽象方法抽象类
// 抽象类、抽象方法:使用abstract关键字定义,抽象方法只能放在抽象类中
// 抽象类和抽象方法用来定义标准,Animal这个父类要求他的子类必须有eat方法
abstract class Animal {
name:string;
constructor(name:string){
this.name = name
}
abstract eat():any
// 非抽象方法子类可以不实现
run():string{
return this.name+`在跑步`
}
}
class Dog extends Animal{
constructor(name:string){
super(name)
}
// 抽象类的子类必须实现抽象类的抽象方法
eat(){
return this.name + `吃肉`
}
}
let dog = new Dog('小狗')
console.log(dog.eat()); //小狗吃肉