2022-07-26 第六组 李俊琦 抽象与接口

今日重点

抽象

接口

学习内容

什么是抽象类

抽象类就是由类与类之间进行共性抽取,进一步抽象而形成的。

abstract关键字

abstract抽象修饰符可以修饰方法和类,使用abstract修饰符修饰的方法称为抽象方法,使用abstract修饰符修饰的类称为抽象类。在抽象方法中是没有方法体的,并且以分号结尾。例如我们定义一个交通工具停止方法,如下:

public class Transport{
    //定义抽象方法
    public abstract void stop();
}

抽象类的定义

抽象类的语法格式
[修饰符列表] abstract class 类名{类体}

当一个类中具有抽象方法时,该类就被视为一个抽象类。

注意:抽象类不能创建对象也就是不能给抽象类创建类的实例(抽象类不能用new创建对象)```

Transportation t=new Transportation();//错误的
Transportation t=new Car();//正确

抽象类的特点

抽象类不能被实例化,只能由子类继承由子类实例化;但是抽象类中有构造方法,这个构造方法是给抽象类的非抽象子类提供的。
抽象类的子类可以是抽象类也可以是非抽象类
inal和abstract不能同时使用,他们是对立的(被final修饰类不能有子类,被abstract修饰的类只有子类继承才能实例化对象)

抽象方法的特点

抽象方法以";"结尾
抽象方法被abstract关键字修饰
抽象方法由非抽象子类来实现

抽象类与抽象方法的关系

抽象类中不一定有抽象方法,但抽象方法一定要写在抽象类中。
非抽象子类继承抽象类,要求非抽象子类必须重写抽象类中的所有抽象方法。

抽象方法的限制

1.final方法不能为抽象方法,这是因为final的方法不能被重写,但是抽象方法必须经过子类重写才能被使用
2.私有方法不能被定义为抽象方法,私有方法并不能被子类继承,而抽象方法必须被子类继承,然后重写实现。
3.静态方法不能被定义为抽象方法,因为抽象方法所在的抽象类是不能创建对象的,也就是不能够被实例化的。但是静态方法是可以通过类名调用,这样调用抽象方法是没有任何意义的
4.抽象类的构造器存在的意义,为了约定子类的构造器必须和父类要匹配
5.一个类如果继承了一个抽象类,就必须重写这个抽象类所有的抽象方法

接口

接口的定义

接口和父类有很多相似的地方,在程序中也是这样的,但是他们表示的含义完全不同。但是接口对外提供的是一个窗口的功能,子类可以同时接收多个接口,而一个子类只能有一个父类,interface是定义接口的关键字,当有该关键字时,就表示这里定义的是一个接口,和class命名的规则相同。abstract关键字并不是必须的,如果定义时不给出系统也会自动加上。当一个类实现一个接口时,需要使用implements关键字,后面跟上接口名,位置是和extends关键字继承父类一样的。接口的定义和实现:

[abstract] interface<J接口名>{
	//定义在接口中的方法与成员变量
}

接口的基础语法

接口是一种引用数据类型,编译后生成字节码文件。
接口是完全抽象的(类是半抽象的),或者说接口是一种特殊的抽象类。
接口与接口之间支持多继承。
接口中只包含常量和抽象方法(java7之前)。
接口中所有的元素都是被public修饰的。
接口中的抽象类在定义时可以省略"public abstract"。
接口中的抽象类不可以省略方法体。
接口中的常量在定义时可以省略"public static final"。
一个非抽象类实现了接口,要求这个类重写接口中所有的抽象类(抽象类可以不重写)
一个类可以实现多个接口
extends和implements可以共存,语法格式是:[修饰符列表] 类名 extends 类名 implement 接口名{}

向下转型问题

类与类之间的向下转型

1.要求类与类之间必须有继承关系,没有继承关系编译器会报错
2.如果两个类之间有继承关系可以通过编译期,但是在运行期也可能出现ClassCaseException

点击查看代码
public class Test2 {
	public static void main(String[] args){
		D d = new A();
		B b = (B)d;
	}
}
class A extends D{}
class B extends D{}

class D{}

在编译期,编译器检测到D的子类有A和B。所以将D类型的d转换成B类型编译器会认为是合法的(骗过编译器)。但是在运行期检测到d实际是A类型,而A类型与B类型没有继承关系(A不是B),无法转换。所以在此处抛出CaseException

接口与接口之间的向下转型

接口与接口之间没有继承关系也可以进行转型,只不过会在运行期可能会出现ClassCaseException

点击查看代码
public class Test3 {
	//接口与接口之间的转型
	public static void main(String[] asrgs){
		
		D d = new A();
		E e = new B();
		E e2 = (E)d;	
		
	}
}
class A implements D{public void method1(){}}
class B implements E{public void method2(){}}

interface D{void method1();}

interface E{void method2();}

可以看出接口与接口之间没有继承关系可以通过编译期,但是在运行期间可能会出现ClassCaseException

在编译期,编译器检查到d是D类型;在运行期,检测到d实际是A类型,而A类型与E类型没有实现关系(A不像E),所以此处会出现异常。那么如果A类型与同时与D类型和E类型有实现关系在运行期间就不会出现ClassCase异常么,我们来看以下代码

点击查看代码
public class Test3 {
	//接口与接口之间的转型
	public static void main(String[] asrgs){
		
		D d = new A();
		E e = new B();
		E e2 = (E)d;	
		
	}
}
class A implements D,E{
	public void method1(){}
	public void method2(){}	
}
class B implements E{public void method2(){}}

interface D{void method1();}

interface E{void method2();}


可以看出如果一个类同时实现了多个接口,哪怕这些接口之间没有继承关系,这些接口之间也能彼此进行转型,同时能通过编译期和运行期

当然这么转型后实现类只能调用转型后接口中的方法,否则无法通过编译期。

类与接口之间的向下转型

1.如果类与接口之间没有实现关系编译期会报错
2.如果类与接口之间有实现关系,在运行期间可能会出现ClassCaseException

抽象类与接口的区别

1.抽象类是半抽象的,接口时完全抽象的
2.抽象类中有构造方法,接口只能没有构造方法
3.接口与接口之间支持多继承,类与类之间只支持单继承
4.一个类可以实现多个接口,但一个抽象类只能继承一个类
5.接口中只允许有常量和抽象方法(java7之前)

接口在开发中的作用

面向接口编程,降低程序之间的耦合度,提高程序的扩展力

posted @ 2022-08-04 16:00  闹市闲人甲  阅读(39)  评论(0)    收藏  举报