【从基础学 Java】继承
来源:互联网 发布:世界史书推荐知乎 编辑:程序博客网 时间:2024/04/24 10:40
和现实世界中:子女可以继承父母的一些特征(如:基因)、财产
等一样。OOP 中也有提供类似的特性,一个类完全可以从其它类里获得一些属性和方法,而不需要我们自己重新定义。这种特性简单但强大 (Simple and powerful)。
快速了解继承
在Java的继承关系里:子类可以从获取父类的所有的公共和受保护成员(字段、方法和内部类)。当然,构造方法不是成员 (members) ,所以不能被继承。同时,在 Java 的继承里,子类可以做如下事情:
- 直接使用继承来的字段
- 直接使用继承来的方法
- 声明和父类同名字段,隐藏 掉父类字段
- 通过父类提供的共有/受保护的方法访问父类的私有成员
- 创建新的字段
- 重写父类同方法签名的实例方法,隐藏 掉父类方法
- 重写父类同方法签名的静态方法,隐藏 掉父类方法
- 编写父类中不存在的方法
- 使用 super 关键字,利用父类构造方法
覆盖
当子类拥有和父类(或接口)同样方法签名的方法,这种现象叫做覆盖。如以下代码:
class Father{ public void doSomthing(){ // Father do something }}class Son extends Father{ @Override public void doSomething(){ // Son do something }}
Java 规定了子类有以下覆盖行为:
- 覆盖父类实例方法
- 覆盖父类静态方法
- 覆盖接口默认方法 (JDK8+)
对于实例方法的覆盖,实际是子类拥有自己的方法。
对于静态方法的覆盖,要记住:静态方法时属于类的,在多态中,调用的始终是类的方法。
Father father = new Son(); Father.staticMethod(); // 这里使用的是父类Father的静态方法
对于接口方法的覆盖,遵循以下原则:
1.实例方法的优先级大于接口方法 (JDK8+)
interface Animal{ default void saySomething(){ // Animal say something }}interface Cow extends Animal{ default void saySomething(){ // Cow say something }}class MyCow implements Cow{ @Override public void saySomething(){ // MyCow say something } Animal myCow = new MyCow(); myCow.saySomething(); // MyCow say something}
2.有共同祖先的接口,先被覆盖的方法(继承深度低)会被后覆盖的方法(继承级别高)覆盖
interface Animal{ default void saySomething(){ // Animal say something }}interface Pig extends Animal{ default void saySomething(){ // Pig say something }}interface BigPig extends Pig{ default void saySomething(){ // BigPig say something }}class MyPig implements Pig, BigPig{ public static void main(String...args){ MyPig myPig = new MyPig(); myPig.saySomething(); // BigPig saySomething() }}
P.S. 如果出现同一继承级别(上例中 BigPig 和 Pig 都继承 Animal 接口)或者子类继承的接口无相关关系,但是接口间有同方法签名的方法,就会出现覆盖冲突。需要用super
关键字指明具体实现哪个接口的方法或者直接覆盖。
interface Run{ default void run(){ // Run run }}interface Car{ default void run(){ // Car run }}class MyCar implements Run, Car{ @Override public void run(){ Car.super.run(); }}
同时,我们需要注意,Java 子类覆盖父类方法,应该:
- 方法的访问权限大于等于父类
- 方法的返回值小于等于父类
- 方法抛出的异常小余等于父类
多态
我们已经知道,子类可以覆盖父类的方法。如果有一个类继承自另外一个类,我们完全可以用一个父类来引用一个子类,如:
class Person{ public void saySomething(){ // Person say something }}class Father{ @Override public void saySomething(){ // Father say something }}class Test{ pubilc static void main(String...args){ Father father = new Father(); Person person = father; // 父类引用子类对象 }}
像这种父类引用子类对象的现象,Java 里叫做多态 (Polymorphism)。在 Java 里,只有满足如下三个条件,才能叫多态:
- 继承关系
- 覆盖方法
- 父类引用子类对象
对于多态方法的运行,编译器会列举所有父类和子类符合调用方法签名(方法名+参数列表)的方法,然后以以下原则编译、调用方法:
- 成员变量(编译和运行都看左边)
- 成员方法(编译看左边,运行看右边)
- 静态方法(编译和运行都看左边)
其中,调用 private, final, static 方法的过程叫静态绑定,否则叫动态绑定。
在使用多态的过程中,最有效的判断语句能否通过编译的方法是:
右边的类是否是(IS-A)左边的类
如示例代码里的 father(Father) IS-A Person。
阻止继承
有些情况下,我们可能不希望子类覆盖父类的方法,这时候,用final关键字修饰方法即可实现该目的。编译器可以对用final的方法进行内联操作优化处理。
强制转换
在多态里,我们知道一个父类可以引用一个子类对象:
Father father = new Son();
但是,反过来就不行了:
Son son = new Father();
如果需要让编译器不报错,我们就得进行强制类型转换操作:
Son son = (Son)new Father();
不过,这么做有风险,我们一般要使用 instanceof
关键字先判断,能否将父类“安全”转换成子类:
Father f = ...;if (f instanceof Son){ Son son = (Son)f;}
抽象类与接口
在继承体系里,比较常用的就是抽象类和接口。它们比较相似:
- 都能被继承
- 都包含抽象方法
- 都不能被实例化
然而,它们还是有不同的,例如:
- 抽象类可以声明非final&&static的字段,接口不行(默认public static final)
- 抽象类可以声明非public方法,接口不行(默认方法是public)
- 一个类只能继承一个抽象类,可以继承多个接口
然后,抽象类和接口有不同的使用场景:P
抽象类:
- 在相关类里共享代码
- 规定了一系列通用的方法和属性
- 需要定义非静态、非共有的方法
接口:
- 定义属性,如可比较 (Comparable)、可飞(Flyable)
- 定义行为,不关心具体实现
- 希望是多继承的一部分
继承的技巧
在 Java 里,我们一般按照如下规则使用继承:
- 将公共操作放在超类(父类)中
- 不要使用受保护的域
- 继承严格遵循
is-a
原则 - 不要过多得使用反射
- 【从基础学 Java】继承
- 【从基础学 Java】序
- 从基础开始学java
- 开始从基础学java之firstday
- Java语法基础,零基础学编程从这里开始
- 从基础学起
- 菜鸟学Java----继承
- 【Android基础学IOS开发】从Java转向Objective-c
- 怎么样从零基础开始学java 新…
- 【从基础学 Java】运算符和数据类型
- 跟我开始从0学Android-Java基础-数据类型
- 要从基础学起..
- 从头开始学java-继承
- 学完JAVA基础
- java 继承的基础
- java继承的基础
- java基础-继承关系
- 基础的Java继承
- 阶乘累加
- Nginx启动、重启失败的一般解决方法和步骤
- 【算法】牛客网前端编程(10-20)
- follow Sam哥课程 Day3
- MySQL 5.7忘记root密码 windows
- 【从基础学 Java】继承
- LeetCode:263. Ugly Number
- c++第二次试验-通过计算说明,这个换钱计划对百万富翁是否是个划算的交易(作业)
- image-style-transfor项目在win10上采用gpu运行的部署
- C++ Primer_4th学习笔记(8)- 数组和指针
- < Unable to ping server at localhost:1099>问题解决---小记
- 实现Runnable接口适合资源的共享
- 设计模式:六大原则
- 求π的近似值