继承和多态密不可分,多态是基于继承实现的。
一、继承性:可以让子类复用父类的方法,如该方法需要调整,只需要在父类中修改方法就行;如果子类有自身的需求,可以编写自身的同名方法,从而覆盖覆盖父类方法。
使用 extends 关键字
子类中已重写了父类方法,要想在子类中调用该父类方法,可以使用super关键字来引用。
例如:super.RunReport();
二、多态性,可以用父类引用指向子类对象或者,将子类对象作为实参,赋值给父类对象。
例1:
例2:形参是父类对象(实现解耦)
三、方法的重载:重载与多态毫无关系。
四、抽象类
抽象类,是为了避免该类创建对象。比如,Animal ani = new Animal(); 因为没有动物这个对象,不适合作为一个对象,所以就使用抽象类。
Dog dog = new Dog(); //Dog继承Animal,是具体的动物,适合new一个对象。
设计抽象类的方法,在类的声明前,添加abstract关键字。(这样当new 抽象类的时候,编译器就会报错。)
抽象类中可以有抽象方法,也可以有非抽象的方法。
如果类中有抽象的方法,则此类必定标识为抽象类。
抽象的方法中没有内容,以分号结尾。
抽象方法,必须在具体类中实现。
抽象类是用于继承的。
1)定义抽象类(抽象类中可以有抽象方法、也可以有具体方法)
public abstract class Animal {
// 抽象方法
public abstract void eat();
// 具体方法
public void sleep() {
System.out.println("Sleeping...");
}
}
2)定义抽象方法
在抽象类中,你可以定义一个或多个抽象方法。这些方法以abstract
关键字开头,并且没有方法体(即没有大括号{}
和实现代码)。例如:
public abstract void move();
3)创建抽象类的子类
要使用抽象类,你需要创建一个继承自该抽象类的子类,并实现所有抽象方法。如果子类中没有实现所有的抽象方法,那么子类也必须被声明为抽象的。例如:
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("Dog is eating");
}
@Override
public void move() {
System.out.println("Dog is moving");
}
}
抽象类的使用场景
-
定义一组接口:当你不确定哪些方法会被所有子类共同使用时,可以使用抽象类来定义一个共同的接口。
-
强制子类实现:通过要求子类实现所有抽象方法,可以确保每个子类都有必要的方法实现。
-
共享代码:虽然不能实例化,但抽象类可以包含一些具体的方法实现,这些方法可以被所有子类共享。
-
作为基类:在面向对象设计中,抽象类可以作为一组相关类的基类,提供共同的属性和行为。
五、抽象的方法
强制子类重定义这个方法,因为父类中的这个方法,可能不是用于所有子类,例如,狗叫和猫叫是不一样的;但这样又有些麻烦。
五、接口
Java中的类不支持多继承(两个父类都具有相同的函数,子类不知道该继承哪个?),所以产生了接口(所有的方法均是抽象方法,强制子类必须重写该函数)。一个类可以实现多个接口(注意不是继承,是实现,所以,接口可以由两个看起来互补相关的类来实现。而继承的话,两个子类是有共同属性的。)
接口,顾名思义,统一了命名规范等规则。不同的类各自实现自己的内容,可以理解为多个类之间的接口。
软件松耦合,声明和实现分离,适合团队开发。只提供方法,不涉及具体实现细节,安全.
接口中将所有的方法都设为抽象的,因此子类就必须实现所有方法。
Java的接口就好像是100%抽象类。
接口的定义,是将类中的class 替换成 interface,使用implements后接接口名称。(接口不能被继承,只能被实现)
实现接口的类,必须要实现它所有的方法,因为这些所有的方法都是public 与 abstract的。
接口中的类成员只能是public static final ,更侧重于方法,一般情况下,不在接口中定义变量。类中可以有成员变量和方法。
抽象父类中增加某个类实现,可以不必修改子类。如果修改接口(实现类必须要实现接口中的所有方法,),子类必定要同步修改。
继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。
接口还可以用来实现不同类之间的常量共享。人们常常使用接口来建立类和类之间的”协议”。
接口的意义是 各个类具备相同的能力,具体怎么实现不关注,例如:拍照能力,具体是使用手机还是相机并不关注。
如上图所示,Dog类继承了Canine类,实现了Pet接口。
如上图所示,Dog类,同时实现了Pet、Saveable、paintable三个接口。
interface IFly {
void fly();
}
class Bird implements IFly{
private String name;
public Bird(String name) {
this.name = name;
}
@Override
public void fly() {
System.out.println(name+"用翅膀飞!");
}
}
class Plane implements IFly{
private String type;
public Plane(String type) {
this.type = type;
}
@Override
public void fly() {
System.out.println(type+"用机翼飞!");
}
}
//测试
public class Test {
public static void main(String[] args) {
//创建接口变量,接收引用
IFly fly1=new Bird("啄木鸟");
IFly fly2=new Plane("战斗机");
fly1.fly();
fly2.fly();
}
}
通过这个例子,我们可以简单体会到接口的强大威力,不同于抽象类需要依赖于类型,只要实现了相关接口,不管是什么类都可以使用接口,这就是接口强大的地方。(即:不是is-a的关系,也能使用,接口更侧重的是具备某种能力 )
可以说,针对接口而非具体类型进行编程,是计算机程序的一种重要思维方式同一套代码可以处理多种不同类型的对象,只要这些对象都有相同的能力,更重要的是降低了耦合,提高了灵活性,使用接口的代码依赖的是接口本身,而非实现接口的具体类型,程序可以根据情况替换接口的实现,而不影响接口使用者。(飞机和鸟不是一个类,但都具有飞的能力)
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.youkuaiyun.com/LEE180501/article/details/128061940
还可以参考该文:
总结:
总结:抽象类是纵向的,代码复用,类似ppt模板,子类可以共享父类的方法和变量。是“is -a”的关系,本身具备的能力。
接口是横向的,统一规范、协议,是具不具备某种能力的关系,不同类之间都具备的某种能力,这种能力是扩展的能力。