Java基础复习 Day11
1. 继承性
1.1 继承主要解决的就是:共性抽取的问题,避免代码复用
父类:主要用来定义共性的属性,方法
子类:共性的属性和方法不用再重复定义,直接继承父类来使用,同时还有自己的独特的属性和方法
父类和子类的关系:子类(狗)就是一个父类(动物),是is-a的关系。关键词:extend
1.2 子类的成员变量和父类的成员变量重名访问规则
在父子类的继承关系中,如果子类的成员变量和父类的成员变量重名时,访问规则如下:
- 直接:通过子类对象.成员变量 (类 对象名 = new 子类();)此时等号左边是谁,就是先访问谁的成员变量,没有则向上找
- 间接:通过成员方法访问成员变量:该成员方法属于谁,就用谁的成员变量,没有则向上找
1.3 当局部变量,子类成员变量,父类成员变量重名时子类方法访问重名变量的问题
局部变量:方法内直接调用
子类成员变量:方法中用关键字this来调用
父类成员变量:方法中用关键字super来调用
//父类
public class BasicDemo {
int num =100;
}
//子类
public class DerivedDemo extends BasicDemo {
int num = 200;
//子类方法访问重名变量
public void showVar(){
int num = 300;
System.out.println(num);//300
System.out.println(this.num);//200
System.out.println(super.num);//100
}
}
public static void main(String[] args) {
DerivedDemo demo = new DerivedDemo();
System.out.println(demo.num);//等号左边是子类,所以num是子类的成员变量,输出200
demo.showVar();// 300 200 100
BasicDemo demo2 = new DerivedDemo();
System.out.println(demo2.num);//等号左边是父类,所以是父类的成员变量,多态关系,所以输出:100
}
1.4 当子类父类的成员方法重名时:
访问规则:看new的是谁就优先调用谁的方法,如果没有就向上找。
//父类
public class BasicDemo {
int num =100;
void method(){
System.out.println("父类重名方法执行。。。");
}
}
//子类
public class DerivedDemo extends BasicDemo {
void method() {
System.out.println("子类同名方法执行。。");
}
}
//main方法
public static void main(String[] args) {
DerivedDemo demo = new DerivedDemo();
demo.method();//子类同名方法执行。。
BasicDemo demo2 = new DerivedDemo();
demo2.method();//子类同名方法执行。。 new的是子类所以调用子类方法
BasicDemo demo3 = new BasicDemo();
demo3.method();//父类重名方法执行。。。
}
1.5 方法的重写(Override)
-
概念:在继承关系中,方法的名称一样,参数列表也一样(覆写,覆盖)
-
注意事项:
-
必须保证父子类间的方法的名称相同,参数列表也相同
可以用@override注解写在方法前面,用来检测是否是有效的正确覆盖重写,推荐写该注解
-
子类方法的返回值必须小于等于父类的返回值类型
★Object类是所有类的公共最高父类
//父类 public class BasicDemo { String method(){ return null; } } //子类 public class DerivedDemo extends BasicDemo { @Override Object method() {//如果用Object作为返回值,则返回值类型大于String,所以报错 反过来则没有关系 //'method()' in 'com.kou.oop.demo04.DerivedDemo' clashes with 'method()' in 'com.kou.oop.demo04.BasicDemo'; attempting to use incompatible return type return null; } }
-
子类方法的权限修饰符必须大于等于父类的权限修饰符
★权限大小关系:public > protected > (default) > private
default:并不是关键字,方法前边什么都不写,留空
//父类 public class BasicDemo { public String method(){ return null; } } //子类 public class DerivedDemo extends BasicDemo { @Override String method() {//如果什么都不写,留空则是(default)格式,访问权限小于public所以报错 //'method()' in 'com.kou.oop.demo04.DerivedDemo' clashes with 'method()' in 'com.kou.oop.demo04.BasicDemo'; attempting to assign weaker access privileges ('package-private'); was 'public' return null; } }
-
1.6. 继承时应该注意的设计原则
-
对于已经使用的类,尽量不要进行修改,而是推荐定义一个新的类,来重复利用其中的共性内容,并且添加新的修改内容
-
所以会发现每个重写的方法都会有一个默认的super.父类方法();就是要把父类的方法拿来重复利用,同时在其下添加新的修改内容
1.7. 继承时,构造方法的访问特点
-
子类构造方法中会有一个默认的super()方法调用,如果什么都不写那么编译器会赠送一个super();所以一定是先调用的父类无参构造方法
//父类 public class BasicDemo { int num = 300; public BasicDemo(){ System.out.println("父类无参构造执行~~~"); } } //子类 public class DerivedDemo extends BasicDemo { public DerivedDemo() { System.out.println("子类无参构造执行----"); } } //Main方法 public static void main(String[] args) { DerivedDemo derivedDemo = new DerivedDemo(); //父类无参构造执行~~~ //子类无参构造执行---- }
-
在子类的构造方法中,可以用super关键字来调用父类重载的构造方法。(也只有子类的构造方法能调用父类构造方法,普通成员方法不能调用)
//父类 public class BasicDemo { int num = 300; public BasicDemo(){ System.out.println("父类无参构造执行~~~"); } public BasicDemo(int num) { this.num = num; System.out.println("父类有参构造执行~~~" + num); } } //子类 public class DerivedDemo extends BasicDemo { int num2; public DerivedDemo() { super(100); System.out.println("子类无参构造执行----"); } public DerivedDemo(int num2){ this.num2 = num2; System.out.println("子类有参构造执行----" +this.num2); } } //main方法 public static void main(String[] args) { DerivedDemo derivedDemo = new DerivedDemo(300); //父类无参构造执行~~~ //子类有参构造执行----300 DerivedDemo derivedDemo1 = new DerivedDemo(); //父类有参构造执行~~~100 //子类无参构造执行---- }
-
super的父类构造调用,必须是子类构造方法的第一个语句。(也就是在子类的构造方法中只能调用一个super,还必须是第一个)
1.8 super关键字的三种用法
- 子类的成员方法中,访问父类的成员变量。super.父类成员变量名
- 子类的成员方法中,访问父类的成员方法。super.父类成员方法名(参数)
- 子类的构造方法中,访问父类的构造方法。super(参数)
1.9 this关键字的用法
- 作用:super关键字用来访问父类方法,而this关键字用来访问本类方法
- 用法:
- 在本类的成员方法中访问本类的成员变量
- 在本类的成员方法中,访问另一个成员方法
- 在本类的构造方法中, 访问另一个构造方法
- 在构造方法中使用this时,this也必须是第一个语句。(此时super()或this()只能有一个,即使this在第一个,默认的super还是会送哦,但不能显示放在第一行)
//父类
public class BasicDemo {
int num = 300;
public BasicDemo() {
System.out.println("父类无参构造执行。。。");
}
}
//子类
public class DerivedDemo extends BasicDemo {
int num;
public DerivedDemo(int num) {
this.num = num;
System.out.println("子类有参构造--" +this.num);
}
public DerivedDemo() {
this(100);
}
public void method(int num){
System.out.println(num);
System.out.println(this.num);
System.out.println(super.num);
this.method1();
}
public void method1(){
System.out.println("另外一个成员方法");
}
}
//main方法
public static void main(String[] args) {
DerivedDemo demo = new DerivedDemo();
//父类无参构造执行。。。
//子类有参构造--100
}
1.10 super和this内存图解
图片来自于某网课,仅做学习目的,侵权请联系删除
1.11 Java封装性的特点
- Java语言是单继承的。一个类的直接父类只能有唯一一个
- Java语言是多级继承的。
- 一个子类的直接父类是唯一的,但是一个父类可以有多个子类。(也就是这个子类有很多兄弟姐妹 哈哈)
- 图片来自于某网课,仅做学习目的,侵权请联系删除