Java面向对象–继承、多态和接口
文章目录
前言
前面提到static静态,这里紧接着写出继承、多态和接口的相关知识。
一、继承
1.1继承的概念
Java中提供了一个关键字extends,用这个关键字,可以让一个类和另一个类建立起父子关系。例如,class B extends A,即为B类继承A类。
特点:
1.子类能继承父类的非私有成员(成员变量、成员方法)
2.子类的对象是由子类、父类共同完成的,因此多张设计图对外暴露了什么成员,对象就可以访问什么成员
好处:
减少了重复代码的编写,提高了代码的复用性
注意:Java是单继承的,Java中的类不支持多继承,但是支持多层继承(单继承)
1.2权限修饰符
用来限制类中的成员(成员变量、成员方法、构造器、代码块…)能够被访问的范围。
修饰符 | 本类里 | 同一个包中的类 | 子孙类 | 任意类 |
---|---|---|---|---|
private | √ | |||
缺省 | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
1.3方法重写
当子类觉得父类中某个方法不好用而无法满足需求时,子类可以重写一个方法名称,覆盖父类这个方法。
注意:重写后,方法的访问,Java会遵循就近原则
技巧:
1.使用Override注解,他可以指定java编译器,检查我们方法重写的格式是否正确,代码可读性也会更好
2.子类重写父类方法时,访问权限必须大于或者等于父类该方法的权限( public > protected > 缺省 )
3.重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小
4.私有方法、静态方法不能重写,否则会报错
1.4子类访问其他成员方法
在子类方法中访问其他成员(成员变量、成员方法),是依照就近原则的(依次在子类局部范围找,子类成员范围找、父类成员范围找),找不到则报错。
在子父类中出现重名的成员,要在子类中使用父类则需要使用super.父类成员变量/父类成员方法。
1.5子类构造器特点
子类构造器都会先调用父类构造器再执行自己。
实现方式:
子类构造器首行默认有super(),它会调用父类无参数构造器;
如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(….),指定去调用父类的有参数构造器。
注意:
super(……)调用父类构造器常见场景是对对象包含父类这部分的成员变量进行赋值;
this(……)的作用是在构造器中调用本类其他构造器;
this和super都必须放在构造器的第一行。
关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
---|---|---|---|
this | this.成员变量 访问本类成员变量 | this.成员方法(…) 访问本类成员方法 | this(…) 访问本类构造器 |
super | super.成员变量 访问父类成员变量 | super.成员方法(…) 访问父类成员方法 | super(…) 访问父类构造器 |
二、多态
多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态。
前提:
有继承/实现关系;存在父类引用子类对象;存在方法重写。
2.1多态的优缺点
1.优点:
在多态形式下,右边对象是解耦合的,更便于扩展和维护;
定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强、更便利。
2.缺点:
多态下不能使用子类的独有功能(通过类型转换解决)
3.类型转换
自动类型转换:父类 变量名 = new 子类()
强制类型转换:子类 变量名 = (子类) 父类
2.2强制类型转换
存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错;
运行时,如果发现对象的真实类型与强转后的类型不同,就会报类型转换异常(ClassCastException)的错误出来。
解决方法:
在强制转换前使用instanceof关键字判断当前对象的真实类型,再进行强转。
待转类 instanceof 所转的类
三、final
final 关键字是最终的意思,可以修饰(类、方法、变量)
修饰类则该类被称为最终类,特点是不能被继承,修饰方法则不能被重写,修饰变量则只能赋值一次。
final修饰引用类型的变量,变量存储的地址不能被改变,但地址所指向对象的内容是可以被改变的。
常量
使用了 static final 修饰的成员变量就被称为常量。
作用:用作系统的配置信息。
命名规范:多个大写英文单词通过下划线连接。
四、抽象类
4.1抽象类的概念
abstract,可以用它修饰类、成员方法;
abstract修饰类,这个类就是抽象类;修饰方法,这个方法就是抽象方法。
public abstract class A {
// 抽象方法:必须abstract修饰,只有方法签名,不能有方法体。
public abstract void test();
}
4.2抽象类特点
1.抽象类中可以不写抽象方法,但有抽象方法的类一定是抽象类;
2.类有的成员(成员变量、方法、构造器)抽象类都具备;
3.抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现;
4.一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义成抽象类。
4.3抽象类的应用场景
一种是:用抽象类,我们可以把子类中相同的代码,包括方法签名都抽上来,这样能更好的支持多态,以提高代码的灵活性;
另一种是:反过来用,我们不知道系统未来具体的业务实现时,我们可以先定义抽象类,将来让子类去继承实现,以方便系统的扩展。
注意:使用final关键字修饰模板方法,可以避免被子类重写
五、接口
Java提供了一个关键字interface,用这个关键字我们可以定义出一个特殊的结构:接口。
public interface 接口名{
//成员变量(常量)
//成员方法(抽象方法)
}
接口的好处:
弥补了类单继承的不足,一个类同时可以实现多个接口。
让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现。
接口的注意事项:
1、一个接口继承多个接口,如果多个接口中存在方法签名冲突,则此时不支持多继承;
2、一个类实现多个接口,如果多个接口中存在方法签名冲突,则此时不支持多实现;
3、一个类继承了父类,又同时实现了接口,父类中和接口中有同名的默认方法,实现类会优先用父类的;
4、一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
总结
本文对继承、多态、final关键字用法和抽象类进行了一个介绍,对其注意事项进行了一个简单的说明。