1.super关键字介绍
super 代表父类的引用,用于访问父类的属性、方法、构造器
2.基本语法 297
代码在com.stulzl.super_.包中
父类A
package com.stulzl.super_;
public class A {
//4 个属性
public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;
//无参构造器
public A() {
}
public A(String name) {
}
public A(String name, int age) {
}
// public void cal() {
// System.out.println("A 类的 cal() 方法...");
// }
public void test100() {
}
protected void test200() {
}
void test300() {
}
private void test400() {
}
}
子类B
package com.stulzl.super_;
public class B extends A{
//访问父类的属性 , 但不能访问父类的 private 属性 [案例]super.属性名
public void hi(){
System.out.println(super.n1+" "+super.n2+" "+super.n3);
}
//访问父类的属性 , 但不能访问父类的 private 方法 [案例]super.方法名(参数列表)
public void ok(){
super.test100();
super.test200();
super.test300();
//super.test400();//不能访问父类private方法
}
//访问父类的构造器(这点前面用过):super(参数列表);只能放在构造器的第一句,只能出现一句!
public B(){
//super();
//super("jack");
super("jack",10);
}
}
3. super关键字细节 298由于内容较多看视频
1. 调用父类构造器的好处(分工明确,父类属性有父类初始化,子类的属性由子类初始化)
2. 当子类中有和父类中的成员(属性和方法名)重名时,为了访问父类的成员,必须通过super,如果没有重名,使用super,this直接访问是一样的效果
3. super 的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用 super 去访问爷爷类的成员; 如果多个基类(上级类)中都有同名的成员,使用 super 访问遵循就近原则。A->B->C
代码在com.stulzl.super_detalil.包中
测试SuperDetail
package com.stulzl.super_detalil;
public class SuperDetail {
public static void main(String[] args) {
D b = new D();
b.sum(); //298
b.test();
}
}
Base类父类是Object
package com.stulzl.super_detalil;
public class Base {//父类是Object
public int n1=999;
public int age =111;
public void cal(){
System.out.println("Base类的cal() 方法……");
}
public void eat(){
System.out.println("Base类的eat() 方法……");
}
}
父类C
package com.stulzl.super_detalil;
public class C extends Base{//父类
//4 个属性
public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;
//无参构造器
public C() {
}
//有参构造器
public C(String name) {
}
public C(String name, int age) {
}
//方法
public void cal() {
System.out.println("A 类的 cal() 方法...");
}
}
子类D
package com.stulzl.super_detalil;
public class D extends C{ //子类
//属性
//public int n1 = 888;
//当子类中有和父类中的成员(属性和方法名)重名时,为了访问父类的成员,必须通过super,
// 如果没有重名,使用super,this直接访问是一样的效果
public void sum(){
System.out.println("B类的sum");
//希望调用父类A中的cal方法 298
//这时,因为子类 B 没有 cal 方法,因此我可以使用下面三种方式
//找 cal 方法时(cal() 和 this.cal()逻辑一样),顺序是:
// (1)先找本类,如果有,则调用
// (2)如果没有,则找父类(如果有,并可以调用,则调用)
// (3)如果父类没有,则继续找父类的父类,整个规则,就是一样的,直到 Object 类
// 提示:如果查找方法的过程中,找到了,但是不能访问, 则报错, cannot access
// 如果查找方法的过程中,没有找到,则提示方法不存在
cal();
this.cal();//等价cal();
super.cal();//找 cal 方法(super.call()) 的顺序是直接查找父类,其他的规则一样
//演示访问属性的规则 298
//n1 和 this.n1 查找的规则是
//(1) 先找本类,如果有,则调用
//(2) 如果没有,则找父类(如果有,并可以调用,则调用)
//(3) 如果父类没有,则继续找父类的父类,整个规则,就是一样的,直到 Object 类
// 提示:如果查找属性的过程中,找到了,但是不能访问, 则报错, cannot access
// 如果查找属性的过程中,没有找到,则提示属性不存在
System.out.println(n1);
System.out.println(this.n1);
System.out.println(super.n1); //找 n1 (super.n1) 的顺序是直接查找父类属性,其他的规则一样
}
public void test(){ //299
//super 的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用 super 去访问爷爷类的成员;
// 如果多个基类(上级类)中都有同名的成员,使用 super 访问遵循就近原则。A->B->C
System.out.println("super.n1="+super.n1);
super.cal();
}
}
4. super关键字和this关键字的比较300
5. 基本介绍
注:这里的父类和子类关系不一定,也有可能是爷爷和孙子的关系
5.1 方法重写的注意事项 302
方法重写也叫方法覆盖,需要满足下面的条件
6. 快速入门 301-302
代码在com.stulzl.override_.包中
测试Override
package com.stulzl.override_;
public class Override01 {
public static void main(String[] args) {
Dog dog = new Dog();
dog.cry();
}
}
父类Animal
package com.stulzl.override_;
public class Animal {//父类
public void cry(){
System.out.println("动物叫唤……");
}
//细节: 子类方法的返回类型和父类方法返回类型一样,302
// 或者是父类返回类型的子类
//比如 父类 返回类型是 Object , // 子类方法返回类型是 String
public Object m1(){
return null;
}
//细节: 子类方法不能缩小父类方法的访问权限
//public > protected > 默认>private
public void eat(){ //302
}
// 细节:这里 Object 不是 String 的子类,因此编译错误 302
// public String m2(){
// return null;
// }
}
子类Dog
package com.stulzl.override_;
public class Dog extends Animal{//子类 301
//解读
//1. 因为 Dog 是 Animal 子类
//2. Dog 的 cry 方法和 Animal 的 cry 定义形式一样(名称、返回类型、参数)
//3. 这时我们就说 Dog 的 cry 方法,重写了 Animal 的 cry 方法
public void cry(){//和父类中的cry方法重写了
System.out.println("小狗叫……");
}
//细节: 子类方法的返回类型和父类方法返回类型一样,302
// 或者是父类返回类型的子类
//比如 父类 返回类型是 Object , // 子类方法返回类型是 String
public String m1(){ //302
return null;
}
//细节: 子类方法不能缩小父类方法的访问权限 302
//public > protected > 默认>private
// protected void eat(){
//
// }
// 细节:这里 Object 不是 String 的子类,因此编译错误 302
// public Object m2(){
// return null;
// }
}
7. 方法重写练习
7.1 请对方法的重写和重载做一个比较 303
7.2 题2 304
1) 编写一个 Person 类,包括属性/private(name、age),构造器、方法 say(返回自我介绍的字符串)。
2) 编写一个 Student 类,继承 Person 类,增加 id、score 属性/private,以及构造器,定义 say 方法(返回自我介绍的信息)。
3) 在 main 中,分别创建 Person 和 Student 对象,调用 say 方法输出自我介绍
代码在com.stulzl.override_exercise.包中
测试OverrideExercise
package com.stulzl.override_exercise;
//1) 编写一个 Person 类,包括属性/private(name、age),构造器、方法 say(返回自我介绍的字符串)。
//2) 编写一个 Student 类,继承 Person 类,增加 id、score 属性/private,以及构造器,
// 定义 say 方法(返回自我介绍的信息)。
//3) 在 main 中,分别创建 Person 和 Student 对象,调用 say 方法输出自我介绍
public class OverrideExercise {
public static void main(String[] args) {
Person person = new Person("jack",30);
System.out.println(person.say());
Student student = new Student("smith",20,123456,99.8);
System.out.println(student.say());
}
}
父类Person
package com.stulzl.override_exercise;
//1) 编写一个 Person 类,包括属性/private(name、age),构造器、方法 say(返回自我介绍的字符串)。
public class Person {
private String name;
private int age;
//构造器
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//返回信息
public String say(){
return "name="+name+" age="+age;
}
//set和get方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
子类Student
package com.stulzl.override_exercise;
//2) 编写一个 Student 类,继承 Person 类,增加 id、score 属性/private,以及构造器,
// 定义 say 方法(返回自我介绍的信息)。
public class Student extends Person{
private int id;
private double score;
//构造器
public Student(String name, int age, int id, double score) {
super(name, age);
this.id = id;
this.score = score;
}
//返回信息
public String say(){//这里体现super的好处,代码复用
return super.say()+" id="+id+" score="+score;
}
//set和get方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}