面向对象基础篇 – 抽象类与接口
抽象类
-
将若干个类中相同的部分提取出来,放在一个新的类中。
-
抽象类一般作为父类使用
-
抽象 : 不具体,模糊,即抽象类中,只声明了存在行为,并没有对行为进行具体实现
例如:
小猫,小狗。他们都会叫,但一个是“喵喵”,一个是“汪汪”
此时我们将“叫”这个行为提取出来,放在一个新类中,让小猫,小狗去继承它
abstract class Animal{
public String name ;
public int age ;
public char gender;
public abstract void jiao();//只声明,不存在具体内容
}
class Dog extends Animal{
/*
当我们继承抽象类之后,必须要对其中的所有抽象方法进行重写
如果不想重新写,那就继续定义为抽象类
如 :
abstract class Dog extends Animal
*/
//这里我们重写方法
public void jiao(){
System.out.println("汪汪");
}
}
class Cat extends Animal{
public void jiao(){
System.out.println("喵喵");
}
}
对于动物来说,每种动物怎么叫,我们是不够清楚的,但是每个动物都有叫这个行为
因此,我们只对这个行为进行声明,当不进行具体实现,这就称之为抽象函数
使用abstract标识符修饰
拥有抽象函数的类也只能是抽象类,同样使用abstract 修饰
-
抽象类的抽象方法,由子类具体实现
-
抽象类无法创建对象
抽象类和一般类的区别
- 唯一的区别就是抽象类中包含了抽象函数,且不能创建对象
- 对于抽象类而言,也可以有构造函数,成员变量,成员函数
- 抽象类保留成员变量和成员方法,作为父类被子类使用
对于abstract 关键字,他不能和谁连用
- final
final 修饰的类 无法被继承,而抽象类一般都是作为父类存在,
final 修饰的方法无法被重写,而子类继承抽象类之后,必须完成对抽象方法的重写
- private
private所修饰的方法可以被继承,但无法被访问,因此子类无法重写
- static
静态函数,属性可以直接通过类名调用,而抽象函数是没有具体的函数体的。静态优先于对象加载进方法区,此时和子类没有任何关习
抽象类的由来
- 当父类只知道子类包含怎样的方法,而无法准确知道子类方法时,创建抽象的父类
例如:
图形 - 三角形,矩形,圆形,这三个子类都有计算面积 计算周长的功能 对于图形类而言 他也应该有
子类共同抽取出来的这两个功能 但是对于图形而言,怎么去算面积?怎么去算周长?不确定
-
分析事物时,发现共性内容,就出现向上抽取,会有这样一种特殊情况,就是功能声明相同的
但是功能主体不同,那么这时也可以进行抽取,但只能抽取方法声明,不抽取方法主体
这种被抽取出来的函数-抽象函数
那么包含了抽象函数的类 也必须抽象的-抽象类 -
对于抽象子类而言
- 要么具体实现抽象方法
- 要么继续定义为抽象类
抽象类的特点
- 抽象类和抽象函数都要被abstract 关键字修饰,抽象函数一定在抽象类中
- 抽象类不能创建对象
- 子类只有重写了父类所有的抽象函数之后,才能创建对象,否则本身也是一个抽象类
没有方法体的函数,不一定是抽象函数,也有可能是本地函数
例如
native
接口
- 接口其实就是抽象类的另外一种表现形式如果某一个抽象类中的所有方法都是抽象函数时,那么就可以用接口这个形式来表现
//例如:
abstract class AbstractTest {
public abstract void showA();
public abstract void showB();
public abstract void showC();
public abstract void showD();
}
//AbstractTest另外一种表现形式:
interface AbstractTestInterFace {
public abstract void showA();
public abstract void showB();
public abstract void showC();
public abstract void showD();
}
接口的特点
-
接口中定义的所有变量都是由public static final 修饰的全局静态常量
可以省略修饰符,但不代表没有
-
接口中定义的函数,都是public abstract 修饰的 - 全局抽象函数
可以省略,但不代表没有
-
接口也不能创建对象
-
一个类只能继承一个类,但可以继承多个接口
接口与抽象类的区别
- 相同点
- 位于继承的顶端,被其他子类实现或继承
- 都不能创建对象
- 都包含了抽象函数
- 不同点
- 抽象类为部分方法提供实现
- 接口只包含抽象函数(JDK1.8之后,接口可以包含一般函数 静态函数 成员函数)
interface Linuxable {
public void linux(); //抽象函数 提供给子类实现的
public default void shell() { //成员函数 提供给子类重写的
System.out.println("shell...");
}
public static void k8s() { //静态函数 不会提供给子类重写的 就算在子父类中 静态函数也不存在重写关系
//静态函数值只供给接口调用
System.out.println("ks8...");
}
}