typeScript 抽象类和接口的区别

本文详细解释了面向对象编程中的抽象类与接口的概念,并对比了两者的区别。介绍了抽象类作为类的抽象,用于捕捉子类的通用特性,而接口则是行为的抽象,定义了一组方法,这些方法必须在实现该接口的类中被实现。

1.什么是抽象类?

抽象类,顾名思义,即类的抽象,从面向对象的角度来想,世界万物都可以用类来定义(男人是个类,女人是个类,奔驰是个类,宝马也是个类),那么抽象类又是类的抽象,举个例子,刚说了男人,女人,它们是不是都有公共的一些的属性和行为方法,都有头,手,脚等属性,吃饭,睡觉等行为,我们是不是可以进一步抽象出“人”这个类,然后让男人,女人去继承这个抽象类,这样他们就有了人的通用特性,然后在抽象类基础上定义各自的特殊属性及方法(比如上厕所,男人要进男厕,女人要进女厕)。

1.1 抽象类的特性!
  1. 不可以被实例化
  2. 含有声明但未实现的方法(也可以包含已实现的方法)
  3. 一个类只能继承一个抽象类
  4. 一旦有了抽象方法,就一定要把这个类声明为抽象类
  5. 子类必须覆盖抽象类的抽象方法
abstract class Human {

  public head;
  public foot;
  public hand;
  
  //已实现的方法
  sleep() { 
        return "睡觉"
    }
 
  //已实现的方法 
  eat() { 
        return "吃饭"
    }
  //未实现的方法
  abstract toilet();
}



class Male extends Human{
//子类必须实现其声明未实现的方法
    toilet() { 
        return "上男厕所"
    }
}



class Female extends Human{
//子类必须实现其声明未实现的方法
    toilet() { 
        return "上女厕所"
    }
}


//不能被实例化
let man = new Human();// 报错 Cannot create an instance of an abstract class.constructor Human(): Human
2.什么是接口?

接口,它是对行为的抽象,而具体如何行动需要由子类去实现,接口的意义在于抽象,不拘细节,从而使同类事物在在同一高度具有通用性及可替代性。

2.1 接口的特性!
  1. 不可以被实例化
  2. 含有声明但未实现的方法
  3. 一个类可以继承多个接口
  4. 子类必须实现其声明未实现的方法
  5. 所有成员都是默认Public的,因此接口中不能有Private成员
  6. 子类必须实现接口的所有成员

看下面的例子,比如奔驰和宝马车有飞行和走水路的功能(其他的车没有)!那么我们可以通过接口来分别实现!

interface plane{
    fly(): string;
}

interface waterWay{
   waterWay(): string;
}

class Baoma implements plane,waterWay{
    fly(): string {
        return "宝马汽车实现了飞的技术"
    }
    waterWay(): string{
         return "宝马汽车实现了水路的技术"
     }
}



class Benci implements plane,waterWay{
    fly(): string {
        return "奔驰汽车实现了飞的技术"
    };
    waterWay(): string{
         return "奔驰汽车实现了水路的技术"
    }
}
let p = new plane();// 报错 'fly' only refers to a type, but is being used as a value here

``这里飞的行为和走水路的行为并不是所有的汽车公有的特性(只有这两辆车有这功能,其他车没有这功能),所以通过接口去实现!

3.抽象类和接口的区别?
  1. 抽象类是类(事物)的抽象,抽象类用来捕捉子类的通用特性,接口是行为的抽象
  2. 接口可以被多成实现,而抽象类只能单一继承
  3. 接口不具备继承的任何具体特点,仅仅承诺了能够调用的方法
  4. 抽象类更多的定义是在一系列紧密相关的类之间,而接口大多数是定义在关系疏松但都实现某一功能的类中

总结抽象类是对类本质的抽象,表达的是 is a 的关系,比如:male is a Human。抽象类包含并实现子类的通用特性,将子类存在差异化的特性进行抽象,交由子类去实现。

接口是对行为的抽象,表达的是 like a 的关系。比如:Baoma like a plane(它有飞的功能一样可以飞),但其本质上 is a Car。接口的核心是定义行为,即实现类可以做什么,至于实现类主体是谁、是如何实现的,接口并不关心。

### 接口抽象类区别及其在OO编程中的使用场景特性 #### 1. 定义上的差异 接口是一种完全抽象的概念,它仅定义了一组方法签名,而不提供任何具体的实现[^1]。相比之下,抽象类既可以包含未实现的抽象方法,也可以包含已经实现了的具体方法[^2]。 #### 2. 继承机制的不同 在许多面向对象的语言中(如Java),一个类只能继承自一个父类,但可以实现多个接口[^3]。这意味着如果需要让某个类支持多种能力时,接口会更加灵活。然而,在某些语言中(如C++或Python),多重继承是被允许的,因此这种限制可能不存在。 #### 3. 方法实现的能力 - **接口**: 只能声明方法而不能给出其实际执行逻辑;但在较新的版本里(比如 Java8),引入了默认(default) 静态(static) 方法来弥补这一局限性[^4]。 - **抽象类**: 不仅有权定义那些子类必须覆盖的纯虚函数(即无主体的方法), 还能够直接编写可供重写或者直接调用的标准操作流程[^5]。 #### 4. 构造器的存在否 由于接口本质上是用来描述行为而不是实体, 所以它们不允许拥有自己的构造器; 而抽象基类则不然——尽管无法实例化自己本身, 却依然可以通过保护级别的构建者初始化一些共有资源供派生出来的具体类型共享利用[^4]. #### 5. 成员变量的支持情况 接口里面除了常量之外不应该存在其他形式的数据成员字段; 对应地讲, 抽象超类别却完全可以设置私有/受保护性质的状态信息用于辅助完成特定业务处理需求[^1]. #### 示例代码展示两种结构如何工作: ```typescript // TypeScript抽象类的例子 abstract class Animal { private name: string; constructor(theName: string){ this.name = theName; } public getName():string{ return this.name; } abstract makeSound():void;// 子类必需覆写的抽象方法 } class Dog extends Animal { constructor(){ super('Dog'); } makeSound(){console.log(`${this.getName()} barks`);} } let d=new Dog(); d.makeSound(); // 输出 "Dog barks" // TypeScript接口的例子 interface Greeting { greet(message:string):void; } class Greeter implements Greeting { greet(message:string){console.log(`Hello! ${message}`)}; } const gtr= new Greeter(); gtr.greet("world"); // 输出 "Hello! world" ``` #### 总结分析 当面临频繁变动的基础功能模块设计抉择时候应该优先选用抽象类而非单纯依赖接口的原因在于前者提供了更多可能性去应对复杂度较高的现实世界建模挑战的同时保持良好的可维护性扩展性[^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值