一、概述

继承描述的是事物之间的所属关系,这种关系是: is-a 的关系。例如,图中的兔子属于食草动物,食草动物又属于动物。继承可以使多种事物之间形成一种关系体系,让父类更通用,子类更具体。

1.1  定义

继承:就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。

1.2  好处

  • 提高代码的复用性
  • 继承是多态的前提

二、 子类继承父类后的特点

2.1  成员变量重名

在子类和父类没有重名的成员变量时,访问是没有任何影响的。如果存在重名,则需要通过super关键字访问父类成员变量,代码如下:

class Fu {
// Fu中的成员变量。
int num = 5;
}
class Zi extends Fu {
// Zi中的成员变量
int num = 6;
public void show() {
// 访问父类中的num
System.out.println("Fu num=" + super.num);
// 访问子类中的num
System.out.println("Zi num=" + num);
}
}
class ExtendsDemo{
public static void main(String[] args) {
// 创建子类对象
     Zi z = new Zi();
// 调用子类中的show方法
z.show();
}
}
演示结果: Fu num = 5 Zi num = 6

通常Fu 类中的成员变量是非私有的,子类中可以直接访问。若Fu 类中的成员变量私有了,子类是不能直接访问的。通常编码时,我们遵循封装的原则,使用private修饰成员变量,想要访问父类的私有成员变量,可以在父类中提供公共的getXxx方法和

setXxx方法。

2.2  成员方法重名

如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。

    方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。代码如下:

        class Fu {
public void show() {
System.out.println("Fu show");
}
}
class Zi extends Fu {
//子类重写了父类的show方法
public void show() {
System.out.println("Zi show");
}
}
public class ExtendsDemo05 {
public static void main(String[] args) {
Zi z = new Zi();
// 子类中有show方法,只执行重写后的show方法
z.show(); // Zi show
}
}
注意事项
  • 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。
  • 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。
  • 子类想要调用父类重名方法,需要添加super关键字。

值得一提的是,重写的方法带有对象参数时,方法调用的优先级为:

  • 1. 先在本类中查找是否有名称和参数对应的方法,有则调用,没有则继续下一步
  • 2. 然后到父类中查找是否有名称和参数对应的方法 ,有则调用,没有则继续下一步
  • 3. 如果子类的父类还有父类,则在父类的父类中查找是否有名称和参数对应的方法 ,有则调用,没有则继续下一步
  • 4. 如果父类已经是最顶层,还没有找到对应的方法,则将对象参数转型为父类,从最初的子类开始找名称和参数对应的方法(即重复1-3步)

代码如下:

class A {

    public void show(A obj) {
System.out.println("A.show(A)");
} public void show(C obj) {
System.out.println("A.show(C)");
}
} class B extends A { @Override
public void show(A obj) {
System.out.println("B.show(A)");
}
} class C extends B {
} class D extends C {
}
public static void main(String[] args) { A a = new A();
B b = new B();
C c = new C();
D d = new D(); // 在 A 中存在 show(A obj),直接调用
a.show(a); // A.show(A)
// 在 A 中不存在 show(B obj),将 B 转型成其父类 A
a.show(b); // A.show(A)
// 在 B 中存在从 A 继承来的 show(C obj),直接调用
b.show(c); // A.show(C)
// 在 B 中不存在 show(D obj),但是存在从 A 继承来的 show(C obj),将 D 转型成其父类 C
b.show(d); // A.show(C) // 引用的还是 B 对象,所以 ba 和 b 的调用结果一样
A ba = new B();
ba.show(c); // A.show(C)
ba.show(d); // A.show(C)
}

可简单的表述为:

  • this.func(this)
  • super.func(this)
  • this.func(super)
  • super.func(super)

2.3  构造方法

定义格式和作用

  • 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
  • 构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个 super() ,表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。代码如下:
class Fu {
private int n;
Fu(){
System.out.println("Fu()");
}
} class Zi extends Fu {
Zi(){
// super(),调用父类构造方法,子类构造函数不写也会在第一行默认调用父类空参构造
super();
System.out.println("Zi()");
}
}
public class ExtendsDemo{
public static void main (String args[]){
Zi zi = new Zi();
}
}
输出结果: Fu() Zi()

三、 抽象类

    如果一个类包含抽象方法,那么该类必须是抽象类。
    定义格式:
abstract class 类名字 {}
    代码举例:
public abstract class Animal {
  public abstract void run();
}

3.1  使用抽象类的注意事项

  • 1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
  • 2. 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的。
  • 3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
  • 4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则,编译无法通过而报错。除非该子类也是抽象类。

四、 接口

4.1 概述
 
    接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法(JDK 9)。
    接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。
    引用数据类型:数组,类,接口。
    接口的使用,它不能创建对象,但是可以被实现( implements ,类似于被继承)。一个实现接口的类(可以看做是接口的子类),需要实现接口中所有的抽象方法,创建该类对象,就可以调用方法了,否则它必须是一个抽象类。
4.2  接口的实现
 
    类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类。实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements 关键字。在继承体系中,一个类只能继承一个父类。而对于接口而言,
一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口。
    非抽象子类实现接口:
    1. 必须重写接口中所有抽象方法。
    2. 继承了接口的默认方法,即可以直接调用,也可以重写。
class 类名 implements 接口名 {
  // 重写接口中抽象方法【必须】
  // 重写接口中默认方法【可选】
}
4.2.1 抽象方法

    接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次。代码如下:

 interface A {
public abstract void showA(); public abstract void show();
} interface B {
public abstract void showB(); public abstract void show();
} public class C implements A, B {
@Override
public void showA() {
System.out.println("showA");
} @Override
public void showB() {
System.out.println("showB");
} @Override
public void show() {
System.out.println("show");
}
}

4.2.2  默认方法

    接口中,有多个默认方法时,实现类都可继承使用。如果默认方法有重名的,必须重写一次。代码如下:
   定义多个接口:

    interface A {
public default void methodA() {
} public default void method() {
}
} interface B {
public default void methodB() {
} public default void method() {
}
} 定义实现类: public class C implements A, B {
@Override
public void method() {
System.out.println("method");
}
}

4.2.3    静态方法

    静态与.class 文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用,代码如下:
    定义接口:

    public interface LiveAble {
public static void run() {
System.out.println("跑起来~~~");
}
} 定义实现类: public class Animal implements LiveAble {
// 无法重写静态方法
}
定义测试类:
public class InterfaceDemo {
public static void main(String[] args) {
Animal.run(); // 【错误】无法继承方法,也无法调用
LiveAble.run(); // 输出结果: 跑起来~~~
}
}

4.2.4  私有方法

    如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中,供默认方法去调用。从设计的角度讲,私有的方法是对默认方法和静态方法的辅助。这里不过多阐述。
4.2.5  优先级问题  
    当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执

行父类的成员方法。
 
 

摘自:黑马程序员讲义

 
 
 
 
 
    
 

JavaSE基础知识之继承的更多相关文章

  1. c++ 基础知识回顾 继承 继承的本质就是数据的copy

    c++ 基础知识笔记 继承 什么是继承 继承就是子类继承父类的成员属性以及方法 继承的本质就是 数据的复制 是编译器帮我们做了很多操作 class Base { public: Base(){ cou ...

  2. JavaSE基础知识总结

    最近回顾了一下Java的基础知识,决定写成博客梳理一遍,主要是JavaSE部分最基础的知识,适合考前突击,学后回顾,不适合作为初学材料. 简单的列个目录吧: 一.数据类型和运算符 二.流程控制与数组 ...

  3. JavaSE 基础知识(常识概念 + 基础语法)问答总结/面试题 —— 讲给应届生的 Java 开源知识项目

    写在最前面 这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解.所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项 ...

  4. JavaSE基础知识(5)—面向对象(5.4面向对象三大特征:封装、继承、多态)

    面向对象编程具有三大特征: 封装 继承 多态 一.封装 1.好处 狭义的封装:也就是属性的封装,避免了任意赋值的危险,提高了数据的安全性! ①隐藏一个类中不需要对外提供的实现细节 ②使用者只能通过实现 ...

  5. java 基础知识十 继承和多态

    java  基础知识十   继承和多态 继承 1.定义: 继承是指声明一些类,可以再进一步声明这些类的子类,而子类具有父类已经拥有的一些方法和属性,这跟现实中的父子关系是十分相似的,所以面向对象把这种 ...

  6. java基础知识总结--继承和接口

    什么是继承?什么是接口?他们之间的区别和联系是什么? 什么是继承? 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能.多个类中存在相同属性和行 ...

  7. javaSE基础知识(走向编程的门口)— 更新完毕

    前言:玩儿编程最重要的一点:不要怕麻烦,感觉是在浪费时间: 能动手绝不哔哔:只要脑袋不傻,编程都是"一看就会,一练就废",开始学的时候,就算再基础的东西都建议手敲一遍 要有囫囵吞枣 ...

  8. C/C++基础知识总结——继承与派生

    1. 类的继承与派生 1.1 派生类的定义 (1) 定义规范 class 派生类名: 继承方式 基类1名, 继承方式 基类2名... { ...派生类成员声明; }; (2) 从以上形式上看可以多继承 ...

  9. JavaSE基础知识(5)—面向对象(抽象类和接口)

    一.抽象类 1.理解 用abstract关键字定义的类,称为抽象类用abstract关键字定义的方法,称为抽象方法意义:当设计父类时,发现该父类根本不需要创建对象,并且里面有不好描述的方法.这个时候往 ...

随机推荐

  1. 将蓝牙rssi(信号强度)转换成距离

    遇到一个问题,是将蓝牙rssi(信号强度)转换成距离的问题. 这一问题没有准确的解决办法,但是有人做过一个拟合回归函数,其变化规律比较类似于rssi的变化规律,函数如下: d = ^(abs(rssi ...

  2. Faster R-CNN论文阅读摘要

    论文链接: https://arxiv.org/pdf/1506.01497.pdf 代码下载: https://github.com/ShaoqingRen/faster_rcnn (MATLAB) ...

  3. LVS集群

    集群: 将许多小的,性能较低的服务器做成一个大的性能高的超级服务器 集群分为负载均衡集群,高可用集群,高性能运算集群 LVS体系结构与工作原理描述 LVS集群负载均衡器接受服务的所有入站客户端计算机请 ...

  4. 保存图片控件上的图片到本地 出现错误:无法将类型为“System.Windows.Media.Imaging.BitmapFrameDecode”的对象强制转换为类型“System.Windows.Media.Imaging.BitmapImage”。

    保存图片控件上的图片到本地 出现错误:无法将类型为“System.Windows.Media.Imaging.BitmapFrameDecode”的对象强制转换为类型“System.Windows.M ...

  5. java数据结构之LinkedList

    一.LinkedList源码注释 //LinkedList源码 jdk版本1.8.0_121 public class LinkedList<E> extends AbstractSequ ...

  6. sql server 备份语句

    1.BACKUP DATABASE your_database TO DISK = 'diff.bak'with DIFFERENTIAL #差异备份,仅备份数据2.BACKUP DATABASE y ...

  7. 计蒜客 —— 字符串p型编码

    给定一个完全由数字字符('0','1','2',…,'9')构成的字符串 strstr,请写出 strstr 的 pp 型编码串. 例如:字符串122344111可被描述为“1个 1.2 个 2.1 ...

  8. golang中字符串内置函数整理

    字符串内置函数 1. 判断字符串的长度 str := "korea国" fmt.Println("str len=", len(str)) 2. 字符串遍历,同 ...

  9. Linux添加日常任务监控文件或日志大小

    1.使用命令"vi/vim xxx.sh"编写shell脚本文件 #!/bin/bash #author yangli # #设置文件检测路径 file_check_path=&q ...

  10. MariaDB基本知识点总结01--介绍+语句

    一.概念 1.数据库介绍: 简单的说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构(数据结构是指数据的组织形式或数据之间的联系)来组织,存储的,我们可以通过数据库提供的多种方法来管理数据 ...