继承封装与多态作为面向对象三大特性,将代码组织起来,使得函数编程的复用性大大提高。其中类与类之间的关系成为组织代码的关键,虚方法,抽象方法,抽象类以及接口概念类似,但是很小的差别也会让使用场景天差地别。本文意在梳理清楚这四个概念,便于编写自己的代码以及看懂他人的代码。
一、接口
1、接口的定义
接口是一组派生类的模板,其本身不提供任何定义与功能,但是可以提供变量、函数的声明,而接口的实现类必须完成接口声明的函数变量的实现。
本身不能包含任何其他的成员,例如:常量、字段、域、构造函数、析构函数、静态成员。
2、接口的作用
因为接口为实现类提供了模板,所以其他类在调用实现类之前,就可以根据接口的声明知道实现类具有哪些属性与方法。即不需要等到具体类实现完成后才调用,而是预先调用了类的方法变量,但是具体的实现可以等到实现类来进行。
3、接口的使用
接口的创建
接口使用 interface 关键字声明,它与类的声明类似。接口声明默认是 public 的。
interface graph
{
void Area();
}
接口的实现
与继承类似
class square: graph
{
int side = 10;
public void Area()
{
return side*side;
}
}
class round: graph
{
int radius = 10;
public void Area()
{
return Math.PI*radius*radius;
}
}
在这个例子中,其他的类不需要管square与round如何编写,但是通过接口知道这两个类一定有Area()这个方法,于是可以在需要的地方直接调用。
二、抽象类
1、抽象类的定义
抽象类与接口类似,不能被实例化,只能被其他类继承。抽象类可以包括抽象方法,抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。
2、抽象类与接口的区别
抽象类就像一个高级些的接口,除了有接口中需要被继承类实现的抽象方法外,还可以定义正常方法,共给所有子类使用。
3、抽象类的使用
抽象类的创建
通过abstract关键字标注,说明该类是抽象类。需要让子类继承的抽象方法需要标注abstract
public abstract class graph
{
void say(){
print("我们都是图形类");
}
public abstract void Area();
}
抽象类的继承
抽象类的实现类需要实现其父类的全部抽象方法才能通过编译。实现时需要添加override关键字,表示对父方法的重写。
class square: graph
{
int side = 10;
public override void Area()
{
return side*side;
}
}
class round: graph
{
int radius = 10;
public override void Area()
{
return Math.PI*radius*radius;
}
}
这样square与round可以拥有自己的Area()方法的同时,还有从父类继承来的say()方法,而不像接口需要全部重写。
三、虚方法
一、虚方法的定义
虚方法是类中可以被重写的方法,他提供给子类重写的权限,如果没有重写,子类则继承自己的方法。
二、虚方法与抽象方法的区别
虚方法可以有方法的实现,且子类可以有选择的重写此方法。如果子类没有重写此方法,则默认使用父类的方法。而抽象方法必须要求子类重写。
三、虚方法的使用
使用关键字virtual将方法标注为虚方法,子类重写时,需要加上override将方法覆盖。
四、总结
虚方法、抽象类以及接口,对子类的自由度是逐步递增的,虚方法可由子类决定实不实现,抽象类中抽象方法由子类定义,而接口的所有方法全部都由子类定义。
在实际开发中,需要根据实际情况来选择对应的方法。