自己的学习笔记,若是有什么错误,麻烦各位前辈指出来,谢谢(ε≡٩(๑>₃<)۶ 一心向学)
继承
继承性是面向对象的第二大特征
主要特点:可以扩充已有类的功能
问题引出
如果不使用继承对程序进行定义,会不可避免的要面对代码的重复问题,下面定义两个类:人类、学生类:
class Person {//人类
private String name ;//姓名
private int age ;//年龄
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}
class Student {//学生类
private String name ;//姓名
private String school ;//学校
private int age ;//年龄
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getSchool() {
return this.school;
}
public void setSchool(String school) {
this.school = school;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}
这个时候可以发现程序中有一些重复的代码
现在可以思索下两者的关系:学生是一个人,人是一个更加广泛的定义,而学生是一个相对狭小的定义,并且学生应该包含人的所有特点。
使用继承定义
package com.test;
class Person {//人类
private String name ;//姓名
private int age ;//年龄
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
}
class Student extends Person {//学生类
private String school ;//学校
public String getSchool() {
return this.school;
}
public void setSchool(String school) {
this.school = school;
}
}
public class JavaDemo {
public static void main(String[] args) {
Student student = new Student();
student.setName("Java");//设置姓名 父类定义
student.setAge(20);//设置年龄 父类定义
student.setSchool("清华大学");//设置学校 子类定义
System.out.println("姓名:" + student.getName() + "、年龄:" + student.getAge() + "、学校:" + student.getSchool());
}
}
运行结果:
实例化流程
class Person {//人类 父类
public Person() {
System.out.println("父类实例化对象");
}
}
class Student extends Person {//学生类 子类
public Student() {
System.out.println("子类实例化对象");
}
}
public class JavaDemo {
public static void main(String[] args) {
new Student();//实例化子类对象
}
}
运行结果:
此时,系统自动调用父类的构造方法(实例化父类对象),实际上相当于子类的构造方法中隐含了一个"super()"语句(此语句只允许放在子类构造方法的首行,且调用父类无参构造方法),若父类没有无参构造,必须使用super() 明确调用有参构造
在实例化子类对象的同时一定会实例化父类对象
继承限制
- Java中不允许 多重 继承,只允许 多层 继承(建议不超过3层);
- 对于私有操作属于隐式继承;
覆写
子类如果发现父类中设计不足并且需要保留父类中的方法或者属性名称的情况下就会发生覆写。
方法覆写
子类定义了与父类方法名称相同,参数类型及个数完全相同
package com.test;
class Ball {
public void play() {
System.out.println("玩球儿 ") ;
}
}
class BasketBall extends Ball { // 继承自Ball类
public void play() {//保留已有的方法名称 进行覆写
System.out.println("在篮球场上打篮球比赛") ;
}
}
public class JavaDemo {
public static void main(String[] args) {
BasketBall basket = new BasketBall() ; // 实例化子类对象
basket.play() ;
}
}
运行结果:
现在实例化的是子类的对象,所以此时调用的方法是子类覆写过的方法,若子类中没有进行方法的覆写,则调用的是父类提供的方法
覆写的意义在于优化父类的功能
覆写限制
- 【public > default(不写) > private】如果父类中的方法使用default权限定义,那么子类定义该方法的时候只能使用public 或 default 定义,如果父类中的方法使用 public 权限定义,那么子类定义该方法的时候只能使用 public 定义;
package com.test;
class Ball {
void play() {
System.out.println("玩球儿 ") ;
}
public void fun() {
this.play(); //调用本类方法
}
}
class BasketBall extends Ball { // 继承自Ball类
}
public class JavaDemo {
public static void main(String[] args) {
BasketBall basket = new BasketBall() ; // 实例化子类对象
basket.fun() ;
}
}
运行结果:
此时虽然实例化的是子类对象,但是子类并没有对父类的play()方法进行覆写
package com.test;
class Ball {
void play() {
System.out.println("玩球儿 ") ;
}
public void fun() {
this.play(); //调用本类方法
}
}
class BasketBall extends Ball { // 继承自Ball类
public void play() {
System.out.println("在篮球场上打篮球比赛") ;
}
}
public class JavaDemo {
public static void main(String[] args) {
BasketBall basket = new BasketBall() ; // 实例化子类对象
basket.fun() ;
}
}
运行结果:
此时实例化的是子类对象,并且子类对父类的play()方法进行了覆写
- 父类中的方法使用 private 权限定义;
package com.test;
class Ball {
private void play() {
System.out.println("玩球儿 ") ;
}
public void fun() {
this.play(); //调用本类方法
}
}
class BasketBall extends Ball { // 继承自Ball类
public void play() {
System.out.println("在篮球场上打篮球比赛") ;
}
}
public class JavaDemo {
public static void main(String[] args) {
BasketBall basket = new BasketBall() ; // 实例化子类对象
basket.fun() ;
}
}
运行结果:
此时并不是一个方法覆写,因为父类的 play() 方法使用 private 权限定义,对于子类不可见,所以这个方法对于子类而言相当于是一个新定义的方法
OverLoading与Override的区别
项目 | OverLoading | Override |
---|---|---|
名称 | 重载 | 覆写 |
概念 | 方法名称相同,参数的类型及个数不同 | 方法名称,参数类型及个数,返回值相同 |
权限 | 无权限限制 | 被覆写的方法不能拥有更严格的控制权限 |
范围 | 发生在一个类中 | 发生在继承关系类中 |