【Java】继承关系与方法覆盖

什么是继承关系?

基于某个父类对象定义的加以拓展,从而产生新的子类定义,子类可以继承父类原来的某些定义,也可以增加原来父类没有的定义,或者覆写父类中的某些特性。

从面向对象的角度上来说,继承是一种从一般到特殊的关系,是一种“ is a ”的关系,即子类是父类的拓展,是一种特殊的父类,比如狗是动物的一种特殊情况,狗属于动物。

在Java语言当中,存在多个类的时候,我们使用“extends”关键字来表示子类和父类之间的关系。

在Java语言当中,类和类之间的继承关系,只允许单继承,不允许多继承,也就是说一个类A,只能有一个直接的父类,不能出现A类同时继承于类B和类C,但是在Java中,允许多重继承

多重继承的例子:
动物有胎生和孪生之分,胎生动物有老虎,老虎又分华南虎,东本虎,孟加拉虎等。

在Java中除了Object类之外,每一个类都有一个直接的父类
比如:class Student extends Person{}
我们就说此时的Student的直接父类是Person,那么Person的父类又是谁呢?
Object类是Java语言的根类(老祖宗,任何类都是Object的子类)
class Person{}等价与 class Person extend Object{}
Object类要么是一个类直接父类,要么是一个类间接父类

继承关系的作用

(1)解决了代码重复的问题
(2)真正的作用,表现出了一个体系。

子类可以继承哪些父类成员?

子类继承父类之后,可以拥有父类的某一些状态和行为(子类复用了父类的功能或状态)
子类到底继承了父类的哪些成员(根据访问修饰符来判断):

(1)如果父类中的成员使用public修饰,子类继承;

(2)如果父类中的成员使用protected修饰,子类也继承,即使父类和子类不在同一个包中;

(3)如果父类和子类在同一个包中,此时的子类可有继承父类中缺省修饰符的成员;

(4)如果父类中的成员使用private修饰,子类打死都继承不到,因为private只能在本类中访问;

(5)父类的构造器,子类也不能继承,因为构造器必须和当前的类名相同。

方法覆盖(复写/覆写)

子类拓展了父类,可以或得父类的部分方法和成员变量。可是当父类的某个方法不适合本身的特征时,此时怎么办?

如:企鹅和鸵鸟是鸟中一个特殊品种,所以企鹅/鸵鸟是鸟类的一个子类,但是鸟类有飞翔的功能,但是对应于企鹅/鸵鸟,飞翔的行为显然不适合它。

这个时候就用到了方法覆盖,如下代码。

创建了一个子类对象Penguin ,并调用fly方法。这个过程其实是先从子类中去寻找fly方法,如果找到就执行,若是找不到,则继续去父类中去找。

//鸟类
clas Bird{
	public void fly(){
		System.out.println("我可以飞翔");
	}
}
//企鹅类
class Penguin extends Bird{
	// 重新定义了fly行为
	public void fly(){
		System.out.println("我不可以飞翔");
	}
}

方法覆盖的原则(一同两小一大):Override
一同:
(1)实例方法签名必须相同(方法签名=方法名+方法的参数列表)

两小:
(2)子类方法的返回值类型是和父类方法的返回类型相同或者其子类;
或者说,子类可以返回一个更加具体的类。如下代码:
但是在实际开发中,没必要这样做,直接使用(1)叙述的就行了

class Bird
{
	public Object fly(){
		System.out.println("fly");
		return null;
	}
}
class Penguin extends Bird
{
	public String fly(){
		System.out.println("Can't fly");
		return "xxx";
	}
}

(3)子类方法声明抛出的异常类型和父类声明抛出的异常类型相同或者是其子类。
子类方法声明抛出的异常类型小于或等于父类方法声明抛出的异常类型;

子类方法可以同时声明抛出多个属于父类方法声明抛出异常类的子类(RuntimeExcption类型除外);

一大:
(4)子类方法的访问权限比父类方法的访问权限更大或相等。

class Person
{
	public void fly(){
		System.out.println("fly");
	}
}

class Student extends Person
{
	// 编译报错,子类方法的访问权限要比父类方法的访问权限更大或相等。
	void fly(){
		System.out.println("Can't fly");
	}
}

private修饰的方法不能被子类所继承,也就不存在覆盖的概念。

判断是否覆盖方法的必杀技:@Override标签:若方法是复写方法,在方法前或上贴上该标签,编译通过,否则,编译出错。

class Person
{
	private void fly(){
		System.out.println("fly");
	}
}
class Student extends Person
{
	@Override
	public void fly(){
		System.out.println("Can't fly");
	}
}
---------- 编译java ----------
ExtendsDemo.java:10: 错误: 方法不会覆盖或实现超类型的方法
	@Override
	^
1 个错误

输出完成 (耗时 0) - 正常终止

注意:
1. 只有方法存在覆盖的概念,字段没有覆盖。

2. 方法覆盖解决的问题:当父类的某一个行为不符合子类具体的特征时,此时子类需要重新定义父类

方法的重载与覆盖的区别

方法重载(Overload)
方法重写(Override)
二者本身没有一点关系,仅仅只是名字很像

方法的重写

作用

解决子类继承父类之后,可能父类的某一个方法不再满足子类的具体特征,此时需要重新定义子类中定义的该方法,并重写方法体;

规则:

1.参数列表必须完全与被重写方法的相同;

2.返回类型必须完全与被重写方法的返回类型相同;

3.访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。

4.父类的成员方法只能被它的子类重写。

5.声明为final的方法不能被重写。

6.声明为static的方法不能被重写,但是能够被再次声明。

7.子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。

8.子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。

9.重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。

10.构造方法不能被重写。

11.如果不能继承一个方法,则不能重写这个方法。

重载

作用:
重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
最常用的地方就是构造器的重载。

规则:
1.被重载的方法必须改变参数列表(参数个数或类型不一样);

2.被重载的方法可以改变返回类型;

3.被重载的方法可以改变访问修饰符;

4.被重载的方法可以声明新的或更广的检查异常;

5.方法能够在同一个类中或者在一个子类中被重载。

6.无法以返回值类型作为重载函数的区分标准。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
重载与覆写/重写的区别 区别 重载 覆写 1 单词 OverLoading Override 2 概念 方法名称相同,参数的类型或个数不同 方法名称相同,参数的类型或个数相 同,返回值类型相同 3 范围 发生在一个类之中 发生在类的继承关系中 4 权限 一个类中所重载多个方法可以不同的权限 被子类所覆写的方法不能拥有比父类更严格 的访问控制权限 重载可以改变返回值类型,但是这样做没有任何的意义, 可是对于覆写而言,绝对不能修改返回值类型,但是在子类中所覆写的方法应该可以继续进行重载。 重载(Overloading)  (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。   重载Overloading是一个类中多态性的一种表现。 (2) Java方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。   调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性。 (3) 重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。     无法以返回值类型作为重载函数的区分标准。 复制代码 /** * 1. 方法重载只可以通过方法名和方法参数来区别,即“方法签名” * @return * @throws NumberFormatException */ public int getSides(Object obj) throws NumberFormatException { return 1; } /** * 2. 不能通过访问权限,返回类型,异常列表进行重载 * * 下面方式错误! */ private Object getSides() throws NumberFormatException, Exception { return 1; } /** * 3. 方法异常类型和数目不会对重载造成影响。 * 下面方式错误! */ public int getSides() throws NumberFormatException, IndexOutOfBoundsException, Exception { } 复制代码 重写(Overriding) (1) 父类与子类之间的多态性,对父类的函数进行重新定义。   如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。   在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。   但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。   方法重写又称方法覆盖。 (2)若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法覆盖原有的方法。   如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。 (3)子类函数的访问修饰权限不能小于父类的;  多态性是面向对象编程的一种特性,和方法无关, 简单说,就是同样的一个方法能够根据输入数据的不同,做出不同的处理,   即方法的重载——有不同的参数列表(静态多态性)   而当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应时,你就要覆盖父类方法, 即在子类中重写该方法——相同参数,不同实现(动态多态性) 复制代码 public class Base { void test(int i) { System.out.print(i); } void test(byte b) { System.out.print(b); } } public class Dog extends Base { void test(int i) { i++; System.out.println(i); } public static void main(String[] agrs) { Base b = new Dog(); b.test(0); b.test((byte) 0); } } 复制代码 这时的输出结果是1 0,这是运行时动态绑定的结果。   简单说来重写就是子类对父类(层级上)中非私有成员方法的重新功能定义。 复制代码 // begin /** * 1. 重写方法必须和被重写方法的“方法签名”一致,即方法名+参数必须相同 */ public int getSides() { return 3; } // end // begin /** * 1. 重写方法访问修饰符一定要大于被重写方法访问修饰符 * (public > protected > default > private) * * 原因: * 2. 有一个可以装1升水的瓶子;你需要用另一个瓶子去继承它, 那你觉得你能用一个半升谁的瓶子继承他吗? */ /** * @return * 本方法重写方式错误 */ // protected int getSides() { // return 3; // } /** * 对父类Shape中getSide方法进行重写,实现多态 * @return */ public int getSides() { return 3; } // end // begin /** * 3. 重写和被重写方法返回值必须相同 * 此方法错误 */ // public double getSides() { // return 3d; // } // end // begin /** * 4. 重写方法抛出的异常必须和被重写方法抛出异常一致,或者是其子类 * 详细见:overrideexception包中例子 */ public int getSides() throws NullPointerException { return 3; } // end /** * 5. 父类中private方法不能被子类重写,因为private只有父类本类可见。 */ /** * 6. 静态方法不存在重写概念,重写是面向对象特性,静态方法是类方法,用类名直接访问。 */ 复制代码
第1章 Java语言概述······························· (1) 1.1 Java语言及其产生···························· (1) 1.2 Java的特点································ (1) 1.3 Java的体系结构····························· (3) 1.3.1 Java的体系结构···························· (3) 1.3.2 Java虚拟机······························ (3) 1.3.3 垃圾回收机制····························· (3) 1.3.4 代码安全检测····························· (4) 1.4 Java的3种版本······························ (4) 1.5 Java开发环境概述···························· (4) 1.5.1 JDK的安装、配置和使用························ (4) 1.5.2 JDK工具箱····························· (6) 1.5.3 Eclipse开发环境的安装、配置和使用··················· (6) 1.5.4 Java程序的编写···························· (7) 1.6 本章小结································· (9) 习题1···································· (9) 第2章 Java语言基础······························ (11) 2.1 Java语言要素······························ (11) 2.1.1 标识符······························· (11) 2.1.2 关键字······························· (11) 2.1.3 分隔符······························· (12) 2.1.4 注释································ (12) 2.2 基本数据类型······························ (13) 2.2.1 简单类型······························ (13) 2.2.2 引用类型······························ (14) 2.2.3 常量································ (14) 2.2.4 变量································ (15) 2.3 运算符和表达式····························· (16) 2.3.1 算术运算符····························· (16) 2.3.2 关系运算符····························· (17) 2.3.3 逻辑运算符····························· (17) 2.3.4 位运算符······························ (18) 2.3.5 赋值运算符····························· (19) 2.3.6 其他运算符····························· (20) 2.3.7 运算符的优先级与结合性························ (21) 2.3.8 表达式与语句···························· (21) 2.4 控制语句································ (22) 2.4.1 选择结构控制语句·························· (23) 2.4.2 循环结构控制语句·························· (25) 2.4.3 转移语句······························ (27) 2.5 数组·································· (29) 2.5.1 一维数组······························ (29) 2.5.2 二维数组······························ (31) 2.5.3 多维数组······························ (32) 2.6 字符串································· (32) 2.6.1 字符串类······························ (33) 2.6.2 常用方法······························ (33) 2.7 综合应用实例······························ (34) 2.8 本章小结································ (37) 习题2···································· (37) 第3章 Java类和对象······························ (39) 3.1 面向对象基础······························ (39) 3.1.1 类································· (39) 3.1.2 对象································ (40) 3.1.3 消息································ (40) 3.2 继承·································· (40) 3.2.1 创建子类······························ (40) 3.2.2 成员变量和方法··························· (41) 3.2.3 对象的构造和初始化过程························ (44) 3.2.4 上转型对象····························· (45) 3.2.5 关键字this和super·························· (47) 3.2.6 对象的撤销和清理·························· (49) 3.3 多态·································· (50) 3.3.1 基本概念······························ (50) 3.3.2 方法重载······························ (50) 3.3.3 方法覆盖······························ (51) 3.3.4 变量覆盖······························ (53) 3.4 修饰符································· (53) 3.4.1 访问修饰符····························· (53) 3.4.2 非访问修饰符···························· (57) 3.5 内部类和匿名内部类··························· (59) 3.5.1 内部类······························· (59) 3.5.2 匿名内部类····························· (61) 3.6 接口·································· (63) 3.6.1 接口的定义····························· (63) 3.6.2 接口与多重继承··························· (63) 3.6.3 接口的实现····························· (64) 3.6.4 接口中的变量和方法························· (64) 3.7 包··································· (66) 3.7.1 包的作用······························ (66) 3.7.2 Java中定义的包··························· (66) 3.7.3 自定义包的创建和使用························ (66) 3.7.4 编译和生成包···························· (67) 3.8 综合应用实例······························ (68) 3.9 本章小结································ (70) 习题3···································· (71) 第4章 Java的I/O流和异常处理·························· (73) 4.1 I/O流概述································ (73) 4.2 System I/O类和Scanner类························· (75) 4.2.1 System I/O类···························· (75) 4.2.2 Scanner类······························ (76) 4.3 文件类································· (76) 4.3.1 使用File类访问文件系统························ (76) 4.3.2 随机文件读写···························· (78) 4.4 字节级输入输出流···························· (79) 4.4.1 数据输入输出流··························· (79) 4.4.2 文件输入输出流··························· (80) 4.4.3 缓冲输入输出流··························· (81) 4.4.4 管道输入输出流··························· (81) 4.4.5 格式化输出流···························· (81) 4.5 字符级输入输出类···························· (82) 4.5.1 字符输入输出类··························· (82) 4.5.2 缓冲读写类····························· (83) 4.5.3 文件读写类····························· (86) 4.5.4 格式化写类····························· (88) 4.6 对象序列化······························· (89) 4.6.1 对象输入流····························· (89) 4.6.2 对象输出流····························· (90) 4.7 异常处理································ (91) 4.7.1 Java中定义的异常·························· (91) 4.7.2 异常类的层次结构·························· (92) 4.7.3 捕获异常······························ (92) 4.7.4 异常处理的嵌套··························· (96) 4.7.5 自定义的异常和使用························· (97) 4.8 文件流综合应用实例··························· (98) 4.9 本章小结································ (106) 习题4··································· (106) 第5章 Java用户界面类和Applet························· (108) 5.1 AWT简介······························· (108) 5.2 AWT容器类······························ (108) 5.3 基本控件类······························· (110) 5.4 图形类································· (112) 5.5 事件类型及其处理··························· (112) 5.5.1 事件类······························ (113) 5.5.2 事件监听器····························· (113) 5.5.3 事件处理流程···························· (114) 5.6 布局管理器······························· (115) 5.6.1 FlowLayout····························· (115) 5.6.2 BorderLayout···························· (116) 5.6.3 GridLayout····························· (116) 5.6.4 CardLayout····························· (116) 5.6.5 GridBagLayout··························· (117) 5.7 Swing简介······························· (117) 5.7.1 Swing组件的特点·························· (118) 5.7.2 Swing包中的类··························· (118) 5.7.3 Swing包中的控件类························· (118) 5.8 Java Applet······························· (122) 5.8.1 Applet简介···························· (122) 5.8.2 Applet程序的编写·························· (124) 5.8.3 Applet程序的编译和执行······················· (125) 5.8.4 Applet的绘图和控制························· (126) 5.9 GUI设计综合应用实例·························· (128) 5.10 本章小结······························· (130) 习题5··································· (130) 第6章 Java网络编程······························ (132) 6.1 Java网络基础······························ (132) 6.1.1 IP地址······························ (132) 6.1.2 端口······························· (133) 6.1.3 套接字······························ (134) 6.1.4 数据报······························ (134) 6.1.5 传输协议······························ (135) 6.2 基于URL的高层次Java网络编程····················· (135) 6.2.1 从URL中读取内容························· (135) 6.2.2 建立URL连接并读取内容······················· (136) 6.3 基于Socket的网络编程························· (137) 6.3.1 Socket通信过程··························· (138) 6.3.2 创建客户端Socket·························· (139) 6.3.3 创建服务器端Socket························· (139) 6.3.4 打开输入输出流··························· (139) 6.3.5 关闭流和Socket··························· (141) 6.4 基于Datagram的网络编程························ (141) 6.4.1 数据报和套接字··························· (142) 6.4.2 创建客户端Datagram························· (142) 6.4.3 创建服务器端Datagram························ (142) 6.4.4 打开输入输出流··························· (143) 6.4.5 关闭流和Datagram·························· (143) 6.5 网络编程与应用实例·························· (144) 6.6 本章小结································ (150) 习题6··································· (150) 第7章 Java多线程编程····························· (152) 7.1 线程基础································ (152) 7.1.1 线程概述······························ (152) 7.1.2 线程的状态····························· (152) 7.1.3 线程的优先级···························· (153) 7.2 线程的创建······························· (153) 7.2.1 通过继承Thread类创建························ (153) 7.2.2 通过实现Runnable接口创建······················ (155) 7.3 多线程的创建······························ (156) 7.4 线程的调度······························· (159) 7.4.1 线程优先级的获取与设置······················· (159) 7.4.2 线程睡眠······························ (159) 7.4.3 线程让步······························ (159) 7.4.4 线程等待······························ (160) 7.4.5 线程唤醒······························ (160) 7.5 多线程的同步处理··························· (161) 7.5.1 多线程的互斥···························· (161) 7.5.2 synchronized方法·························· (161) 7.6 多线程综合应用实例·························· (164) 7.7 本章小结································ (168) 习题7··································· (168) 第8章 数据库编程······························· (170) 8.1 数据库基础······························· (170) 8.1.1 关系数据库····························· (170) 8.1.2 SQL基本内容···························· (171) 8.1.3 ODBC技术····························· (173) 8.2 JDBC数据库连接技术·························· (174) 8.2.1 JDBC概述····························· (174) 8.2.2 JDBC的实现及其驱动程序······················ (174) 8.2.3 JDBC的常用类和接口························ (175) 8.3 Java访问数据库的基本步骤······················· (176) 8.3.1 加载驱动程序类··························· (176) 8.3.2 建立JDBC连接··························· (177) 8.3.3 执行SQL语句··························· (179) 8.4 JDBC高级特性····························· (180) 8.4.1 预备语句······························ (180) 8.4.2 可滚动和可更新的结果集······················· (180) 8.4.3 元数据······························ (182) 8.4.4 事务······························· (183) 8.5 创建数据库······························· (184) 8.6 JDBC综合应用举例··························· (185) 8.7 本章小结································ (187) 习题8··································· (188) 第9章 Servlet与JSP······························ (189) 9.1 Java EE Web开发技术·························· (189) 9.2 Servlet基础······························· (190) 9.2.1 Servlet定义····························· (190) 9.2.2 Servlet工作方式··························· (191) 9.2.3 Servlet API····························· (192) 9.2.4 Servlet异常····························· (193) 9.3 配置Servlet工作环境·························· (193) 9.3.1 Servlet开发环境··························· (193) 9.3.2 Servlet类的配置··························· (194) 9.3.3 编写简单的Servlet·························· (195) 9.4 JavaBean基础······························ (196) 9.4.1 JavaBean基本概念·························· (196) 9.4.2 JavaBean的属性、方法和事件····················· (197) 9.4.3 一个简单的JavaBean························· (197) 9.5 JSP概述································ (198) 9.5.1 JSP基本概念···························· (198) 9.5.2 JSP技术的特点··························· (199) 9.5.3 JSP的工作方式··························· (199) 9.5.4 JSP和Servlet的区别························· (200) 9.6 编写简单的JSP····························· (200) 9.7 在JSP中访问数据库··························· (200) 9.8 JSP的设计模式····························· (202) 9.8.1 JavaBean与JSP的结合························ (202) 9.8.2 Servlet与JSP的结合························· (203) 9.9 JSP的语法要素····························· (203) 9.9.1 JSP脚本元素···························· (203) 9.9.2 JSP指令和动作元素························· (205) 9.9.3 JSP内置对象···························· (206) 9.10 Web综合应用实例··························· (209) 9.11 本章小结······························· (222) 习题9··································· (223) 第10章 RMI和EJB······························ (224) 10.1 RMI基础······························· (224) 10.1.1 RMI概述···························· (224) 10.1.2 RMI的目标和体系结构······················· (224) 10.1.3 RMI的工作机制·························· (225) 10.1.4 用RMI设计应用系统························ (226) 10.2 RMI API································ (227) 10.3 Java RMI与其他分布式技术······················· (228) 10.4 RMI部署问题····························· (229) 10.5 编写一个RMI应用系统························· (229) 10.6 EJB技术································ (233) 10.6.1 EJB基本概念··························· (233) 10.6.2 EJB组件····························· (234) 10.6.3 EJB容器····························· (235) 10.6.4 开发和部署EJB·························· (236) 10.6.5 EJB和其他分布式技术······················· (237) 10.6.6 基于EJB的Web应用程序实例···················· (238) 10.7 本章小结······························· (244) 习题10··································· (245) 附录A Java运算符及其优先级·························· (246) 附录B Java类路径和类加载器·························· (247) 参考文献···································· (249)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值