Java——面向对象进阶(抽象类,接口)
一、抽象类
抽象类:说不清楚的类
抽象方法:说不清楚的方法
方法功能声明相同,但方法功能主体不同。那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。
1、定义抽象类:
当定义了抽象函数的类也必须被abstract关键字修饰,被abstract关键字修饰的类是抽象类。
/* * 抽象类,不能实例化对象, 不能new的 * 不能创建对象的原因: 如果真的让你new了, 对象.调用抽象方法,抽象方法没有主体,根本就不能运行 * 继承他的子类必须要重写定义的抽象方法 */ public abstract class Develop { //抽象类 public abstract void work(); //抽象方法 }
2、特点:
1、抽象类和抽象方法都需要被abstract修饰。抽象方法一定要定义在抽象类中。
2、抽象类不可以直接创建对象,原因:调用抽象方法没有意义。
3、只有覆盖了抽象类中所有的抽象方法后,其子类才可以创建对象。否则该子类还是一个抽象类。
之所以继承抽象类,更多的是在思想,是面对共性类型操作会更简单。
3、疑问:
1、抽象类一定是个父类?
是的,因为不断抽取而来的。
2、抽象类中是否可以没有抽象方法?如果可以,那么,该类还定义成抽象类有意义吗?为什么?
可以没有抽象方法,有意义,不会让其他人直接创建该类对象
3、抽象关键字abstract不可以和哪些关键字共存?
- 1、private:私有的方法子类是无法继承到的,也不存在覆盖,而abstract和private一起使用修饰方法,abstract既要子类去实现这个方法,而private修饰子类根本无法得到父类这个方法。互相矛盾。
- 2、final:最终,固定住变量的的值。
- 3、static:静态方法,可以直接用类名.方法名调用。
二、接口
接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”。
接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成。这样将功能的定义与实现分离,优化了程序设计。
1、定义接口
与定义类的class不同,接口定义时需要使用interface关键字。
定义接口所在的仍为.java文件,虽然声明时使用的为interface关键字的编译后仍然会产生.class文件。这点可以让我们将接口看做是一种只包含了功能声明的特殊类。
public interface 接口名{
抽象方法1; //只能定义抽象方法和定义常量
抽象方法2;
抽象方法3;
}
定义抽象方法的格式:public abstract 返回值类型 方法名字(参数列表);
- 修饰符必须是public(可以不写)
定义常量:public static final 数据类型 变量名 = 值
- 前三个字段为固定格式(可以不写)
- public 权限
- static 可以被类名直接.调用
- final 最终,固定住变量的值
2、实现接口
接口的实现,相当于类的继承
class 类名 implements 接口{
重写接口中方法 // 必须重写
}
3、接口的特点
1、接口中可以定义变量,但是变量必须有固定的修饰符修饰,public static final 所以接口中的变量也称之为常量,其值不能改变。后面我们会讲解static与final关键字
2、接口中可以定义方法,方法也有固定的修饰符,public abstract
3、接口不可以创建对象。
4、子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。否则子类是一个抽象类。
public static final interface Demo { //定义一个名称为Demo的接口。 public static final int NUM = 3; // NUM的值不能改变 public abstract void show1(); public abstract void show2(); } //定义子类去覆盖接口中的方法。类与接口之间的关系是 实现。通过 关键字 implements class DemoImpl implements Demo { //子类实现Demo接口。 //重写接口中的方法。 public void show1(){} public void show2(){} }
4、接口的多实现
interface Fu1 { void show1(); } interface Fu2 { void show2(); } class Zi implements Fu1,Fu2 // 使用,同时实现多个接口。 { public void show1(){} public void show2(){} }
多继承的弊端:多继承时,当多个父类中有相同功能时,子类调用会产生不确定性。其实核心原因就是在于多继承父类中功能有主体,而导致调用运行时,不确定运行哪个主体内容。
多实现没有这种弊端,因为接口中的功能都没有方法体,由子类来明确。
5、继承类+实现接口
//定义父类 class Fu { public void show(){} } //定义接口 interface Inter { pulbic abstract void show1(); } //继承父类+实现接口 class Zi extends Fu implements Inter { public void show1() { } }
接口的出现避免了单继承的局限性。父类中定义的事物的基本功能。接口中定义的事物的扩展功能。
6、接口的多继承
不仅类可以继承,接口也可以,只不过接口支持多继承。
interface Fu1{ void show(); } interface Fu2{ void show1(); } interface Fu3{ void show2(); } interface Zi extends Fu1,Fu2,Fu3{ void show3(); }
在开发中如果多个接口中存在相同方法,这时若有个类实现了这些接口,那么就要实现接口中的方法,由于接口中的方法是抽象方法,子类实现后也不会发生调用的不确定性。
总结:接口在开发中的它好处
-
接口的出现扩展了功能。
-
接口其实就是暴漏出来的规则。
-
接口的出现降低了耦合性,即设备与设备之间实现了解耦。
7、接口和抽象的相同点和区别
相同点:
-
都位于继承的顶端,用于被其他类实现或继承;
-
都不能直接实例化对象;
-
都包含抽象方法,其子类都必须覆写这些抽象方法;
区别:
-
抽象类为部分方法提供实现,避免子类重复实现这些方法,提高代码重用性;接口只能包含抽象方法;
-
一个类只能继承一个直接父类(可能是抽象类),却可以实现多个接口;(接口弥补了Java的单继承)
-
抽象类是这个事物中应该具备的你内容, 继承体系是一种 is..a关系
-
接口是这个事物中的额外内容,继承体系是一种 like..a关系
继承类+实现接口 ==> 他是一个人(类),但是他像一个小偷(接口)
二者的选用:
-
优先选用接口,尽量少用抽象类;
-
需要定义子类的行为,又要为子类提供共性功能时才选用抽象类;