目录
Java的继承:实现代码复用的手段之一
- 一个类与另一个人类的关系
- extends - 拓展而非继承
- “is a”
- 从“一般到特殊”的关系(人 → 老师 → IT老师 → Java老师)
//Java中子类继承父类的语法格式为
修饰符 class SubClass extends SuperClass{
//类定义部分
}
现实中的继承
- 一个实例与另一个实例的关系
- “捞到”财富
//Fruit类(SuperClass)
public class Fruit {
public double weight;
public void info() {
System.out.println("我是一个水果!重"+weight+"g!");
}
}
//Banana类,继承了Fruit
public class Banana extends Fruit{
public static void main(String[] args) {
//创建一个Banana对象
Banana b=new Banana();
//其实呢,Banana本身是没有weight成员变量
//但是Banana的父类Fruit有weight成员变量,而且Banana类继承了Fruit类的weight变量
b.weight=54.5;
//调用Banana对象的info()方法
b.info();
}
}
Java的继承,单继承,extends 后只有一个父类
子类继承了父类,就可以获得父类的
- Field(成员变量)
- 方法
- 子类的构造器总会调用父类的构造器【一次】
如果你定义的Java类没有显式指定父类,系统会默认让他继承object类
“仪器类都是object类的子类”
===============================================================
方法重载(Overload):两同,一个不同
方法重写(Override,也叫覆盖):两同、两小、一大
- 两同
- 方法名相同
- 形参列表相同
- 两小
- 子类重写的方法的返回值类型必须比父类方法的返回值类型更小、或相等
- 子类重写的方法的声明抛出的异常必须必父类方法的声明抛出的异常更小、或相等、
- 一大
- 子类重写的方法的访问权限必须比父类方法的访问权限更大、或相等
此外,覆盖方法和被覆盖方法要么都是实例方法要么都是类方法,不能一个是实例
@Override 让编译器执行更严格的检查,要求被修饰的方法,必须是重写父类的方法
public class Fish {
public void swim() {
System.out.println("我在大海里自由自在游泳……");
}
}
public class Shark extends Fish {
public void swim() {
System.out.println("我是一条鲨鱼,我在大海里自由自在的游泳");
}
public static void main(String[] args) {
Shark sh = new Shark();
//将输出"我是一条鲨鱼,我在大海里自由自在的游泳"
sh.swim();
}
}

=================================================================
super限定
super限定的语法格式:
public void callOverridedMothod{
//在子类方法中通过super限定显式调用被覆盖的方法
//既可以调用重写的方法,又可以调用父类的方法
super.swim();
}
- super限定:强制去使用父类方法
- super调用:用于显式调用父类的构造器
- 规则:子类的构造器【总会】调用父类的构造器【一次】
- 默认情况下,子类构造器会自动调用父类无参数的构造器
- 如果希望明确指定子类构造器调用父类的哪个构造器
- 可用super(参数)来调用
- super调用必须出现在构造器第一行
- super不能出现在static修饰的类方法中,super是指向实例的
/*
* public class:是JAVA定义的,一般占到编程的角度来将就是包含main方法的,
* 一个java文件中只有一个public class,而且public class的文件名要跟.java的文件名一致;
*
* class:在Java编程是描述对象的,也就是类。
*/
//super限定词
class BaseClass {
public int a=5;
}
public class SubClass extends BaseClass{
public int a=7;
public void accessOwner() {
System.out.println(a);
}
public void accessBase() {
//通过super关键字来限定调用的a实例变量
System.out.println(super.a);
}
public static void main(String[] args) {
SubClass sub = new SubClass();
sub.accessOwner(); //输出7
sub.accessBase(); //输出5
}
}

在查找子类中的a的顺序为:
- 查找该方法中有没有局部变量a
- 查找当前类中有没有成员变量a
- 查找a的直接父类中是否包含名为a的成员变量,依次上溯a的所有父类。直到java.lang,Object
【注意】
- 系统在为程序分配内存时,子类n个实例变量与父类m个实例变量(即使有同名的实例变量)依然为保存n+m个实例变量
- 继承中强制向上转型
class Parent{
public String tag = "我正在学习Java";
}
class Son extends Parent{
private String tag = "我正在学习Java基础";
}
public class HideTest {
public static void main(String[] args) {
Son s = new Son();
//如果直接使用s.tag会出现编译失败,因为private的修饰符只允许本类中访问其成员变量
System.out.println(((Parent)s).tag);
}
}

==========================================================================================
调用父类构造器
- 子类不会获得父类的构造器,但是子类构造器中可以调用父类构造器的初始化代码
- super调用、this调用都必须出现在构造器的第一行
- super调用、this调用不能同时出现
class Base{
public double size;
public String name;
public Base(double size,String name) {
this.size=size;
this.name=name;
}
}
public class Sub extends Base{
public String color;
public Sub(double size,String name,String color) {
//通过super调用来调用父类构造器的初始化过程
super(size,name);
this.color=color;
}
public static void main(String[] args) {
Sub sub=new Sub(5.56,"M4A1自动步枪","绿色");
System.out.println(sub.size+"---"+sub.name+"-----"+sub.color);
}
}

【注意】
- 如果既没有super调用也没有this调用,子类构造器会自动先调用父类无参数构造器
- 如果有super调用(必须在子类的第一行),子类构造器会根据super调用传入的参数去调用父类对应的构造器
- 如果有this调用,子类构造器会先找this调用所对应子类中被中被重载的构造器
- this调用和super调用很像,this调用的是当前类的重载构造器,而super调用的是父类的构造器
- 构造器初始化是从最高的父类Object开始依次初始化的
本文深入探讨Java中的继承机制,包括如何实现代码复用,方法重写的规则(两同、两小、一大),super关键字的使用,以及子类如何调用父类的构造器。通过具体实例,如Fruit类与Banana类的继承关系,阐述继承的实际应用。
316

被折叠的 条评论
为什么被折叠?



