继承和接口


一、      抽象类
抽象类和接口的关系非常紧密,都必须有要实现的成员。它们最大的区别是由抽象类可以派生出一些成员的实现,但接口却不包含任何成员的实现。当派生出的事物都属于同一个种类时,此时可用抽象类;当派生出的事物的功能要求完全不同的类对象时,就要用接口实现。
抽象类要求至少有一个抽象成员,抽象成员就是在派生类中必须被的成员。
抽象类使用关键字abstract声明。
虚方法也要使用关键字abstract声明。
 
重写方法和属性
在方法或属性上加上关键字override
调用基类方法
base.Method
替代方法和属性
有时需要阻止多态行为,或在基类中为某个类成员使用一个名称,而在派生类中却要以一种新的方式使用该名称,这称为“屏蔽”。可通过new修饰符实现。
二、      面向对象程序设计的几条基本规则
1、    保持少量的公共接口,大约6个左右的公共成员最适宜。
2、    许多类使用的是简单的接口,而不使用一些庞大复杂、能完成所有功能的方法。
3、    尽可能地使用私有方法来支持公共行为;强烈推荐多使用单值方法,少使用复杂庞大的方法(无论别人怎么说,最后这句是关键)。
4、    在了解更多系统需求的时候,如果感觉有错误就改正它。
5、    如果考虑到类的用户可能需要扩展类的行为,可使用protected和abstract修饰符。
有一些书籍建议读者在不知道如何重用泛化类时,一律把方法定义为受保护的虚方法,但这样会使得程序过于庞大,并且程序运行速度也会变慢)。
方法是用来创建新行为的。拥有越多的方法,就有更多的方式来组合这些方法。类是描述系统的实体。拥有的类越多,在描述系统时就具有更大的灵活性。如果系统出现错误,那么错误将较多地出现在那些受保护类型和私有类型的方法和类中,而较少地出现在公共方法中。复杂庞大的方法和子过程通常是一个系统不健全、扩展性不好的标志。
三、      继承与聚集
当从现有的基类派生一个新类时(也就是继承的时候),将得到这个基类所有成员的一个副本。这被称为“is-a”关系。
当一个类包含另外一个对象时,称为“包含”(containment)或者“聚集”(aggregation)。当根据被包含类的实现来定义容器类成员时,能使得容器类在其外观和行为上类似于被包含的类。聚集关系可称为一个“has-a”关系。
聚集能够完成一些和派生类相同的操作,但是不能通过“is-a”测试。
如果要想使派生类和父类具有相同的类型成员,则应选用继承;如果需要定义一个“整体-部分”的关系,也就是,被包含的对象是包含它的对象的一部分,则应选用聚集;如果需要改进被包含对象的接口,例如,当一个类有很多不符合需求的特征和公共成员时,则需要将现有的类包装在一个新类中,并仅使得符合新需求的那些成员可见。
四、      定义接口
接口定义了一种“契约”(contract)。确切地说,一个接口就是一个类型,它包括方法、属性、和事件的头部,但不包含实现代码。接口能够被继承及实现,其中继承是扩展这种契约的一种方法。
接口自身不能被创建,内容也不能被充实和给出实现代码。当.Net类接受一种接口契约时,类就必须实现接口定义的所有成员,这也是契约责任的关键。
1、        接口的基本准则
1)        接口定义方法、属性和事件签名,但不包含实现。
2)        接口可以执行任意类型的访问,即接口能够使用任何访问修饰符。接口的成员永远是公共的,不能用任何访问修饰符。
3)        接口可以嵌套。
4)        接口可以实现为共享的、抽象的或者虚成员。
5)        不能对接口成员附加安全属性。
6)        接口被看作恒定不变的,一旦您出于使用目的而发布了接口,就不应该改变这个接口。通常应该创建一个新的接口来扩展现有接口。
7)        与类一样,在接口中最好只定义几个关系紧密的成员,成员过多将使得接口变得笨重而难以使用。这样的接口称为“factoring”接口。
8)        用前缀“I”来区分接口和类,并且用Pascal命名方式(Pascal-casing)方式来命名接口(在Pascal命名方式中,每个单词的首字母大写,例:IMInterface)
9)        不能创建接口的实例。
五、      比较抽象类和接口
1、    抽象类可被部分实现,而接口需要完全实现。
2、    类支持单继承,接口支持多继承。
3、    如果继承一个抽象类,当你类更新时,所有的子类都会跟着更新;而接口是一成不变的,一旦发布了一个接口,永远不要再更改它。
4、    如果行为跨越不同类的对象,可使用接口。对于一些相似类的对象,用继承。
5、    使用接口来支持少量的附加功能,对于很多关联功能,可使用抽象类。

 
在面向对象编程中,**继承(Inheritance)****接口(Interface)**是两种不同的机制,分别用于代码的复用与行为的定义。 ### 继承的基本概念 继承是一种使子类能够获得父类属性方法的能力。通过继承,子类可以扩展或修改从父类继承的功能[^4]。例如,在C#中,一个类可以通过冒号 `:` 来继承另一个类: ```csharp public class Engine { public void Start() { Console.WriteLine("Engine started."); } } public class Car : Engine { public string Model { get; set; } public int EngineCapacity { get; set; } } ``` 在这个例子中,`Car` 类继承了 `Engine` 类的方法属性,并且可以添加新的成员或者覆盖已有的成员[^4]。 继承的一个关键特性是它支持层次化的分类,即从一般到特殊的演化过程。然而,继承也有其局限性,比如可能导致类之间的耦合度增加,以及在多层继承结构中可能出现的复杂性[^2]。 ### 接口的基本概念 接口则是一种定义行为规范的方式,它不提供具体的实现,而是规定实现该接口的类必须具备哪些方法、属性等。接口的本质在于抽象行为[^3]。例如,在C#中定义一个接口如下: ```csharp public interface IStartable { void Start(); } ``` 任何实现了 `IStartable` 接口的类都必须提供 `Start()` 方法的具体实现。这种方式允许不同类之间共享相同的行为定义,而不需要关心这些类是如何具体实现这些行为的。 接口的实现机制要求类必须显式地提供接口中声明的所有成员的实现。这使得接口非常适合用来定义跨多个不相关类的公共行为[^5]。 ### 继承接口的区别 1. **功能复用 vs 行为规范**:继承主要用于复用已有类的功能,而接口则用于定义一组操作规范。 2. **实现方式**:继承可以直接使用父类的实现,而接口仅提供方法签名,需要类自己实现这些方法。 3. **多重性**:大多数语言只允许单继承,但允许多个接口的实现。 4. **设计目的**:继承强调的是“是什么”的关系,而接口强调的是“能做什么”的关系。 5. **灵活性**:接口提供了更高的解耦程度,适合于设计松耦合的系统。 ### 最佳实践指南 - **继承使用场景**:当有一个明确的层级关系,并且子类确实是父类的一种特殊形式时使用继承。 - **接口使用场景**:当需要定义一个类型的行为规范,并且希望这个规范可以被完全无关的类所实现时使用接口。 - **设计原则**:优先使用接口而不是继承来降低组件间的依赖度,提高系统的可维护性扩展性。 综上所述,继承接口各自适用于不同的情况,理解它们之间的差异有助于编写更加清晰高效的代码。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值