类和对象进阶 - 继承

 

1. 继承

1.1 继承解决了什么问题 ? java中如何实现继承 ?

对类的共性进行抽取 对代码进行复用     java中, 使用extends关键字 关联
 
查看代码
/*
class Dog {
public String name;
public int age;
public float weight;
public void eat() {
System.out.println(name + "正在吃饭");
}
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
class Cat {
public String name;
public int age;
public void eat() {
System.out.println(name + "正在吃饭");
}
public void sleep() {
System.out.println(name + "喵叫");
}
}*/
// 发现上述代码 有很多重复的地方
// 继承用来 复用代码
//
class Animal {
public String name;
public int age;
public void eat() {
System.out.println(name + "正在吃饭");
}
}
class Dog extends Animal{
public String color;
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
class Cat extends Animal{
public void sleep() {
System.out.println(name + "喵叫");
}
}
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "小白";
System.out.println(cat.name);
Dog dog = new Dog();
dog.name = "大黄";
System.out.println(dog.name);
}
}
 

1.2 子类继承父类什么 ?  子类对象如何存储 ?

子类继承父类的成员变量和方法,除了父类构造方法和父类中的静态成员

查看代码
 class Animal {
public String name;
public int age;
public static int id = 1;
public void eat() {
System.out.println(name + "正在吃饭");
}
}
class Dog extends Animal{
public String color;
public void sleep() {
System.out.println(name + "正在睡觉");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = "a";
dog.age = 2;
}
}

分为两块 一部分存储父类的 一部分存储子类自己的

 

 

1.3 访问优先级

子类与父类存在同名成员时,优先访问子类自己的成员变量/方法如果访问的成员方法子类中无,则访问父类继承下来的如果父类也没有定义,则编译报错

查看代码
 class Base {
public int a = 1;
public int b = 2;
public void test() {
System.out.println("Base::test()");
}
}
class Derived extends Base {
public int a = 10;
public int c = 3;
public void test() {
System.out.println("Derived::test()");
}
public void test2() {
System.out.println("Derived::test2()");
}
public void test(int a) {
System.out.println(a);
}
public static void main(String[] args) {
Derived derived = new Derived();
// 存在同名成员时,优先访问子类自己的成员变量 / 方法
// 访问的成员方法子类中无,则访问父类继承下来的
// 如果父类也没有定义,则编译报错
System.out.println(derived.a);
derived.test();
derived.test2();
}
}

 

1.4 super关键字

super 表示父类数据对象的引用, 用来指定访问 父类成员
 
this 表示对象的引用

 

查看代码
class Base {
public int a = 1;
public int b = 2;
public void test() {
System.out.println("Base::test()");
}
}
class Derived extends Base {
public int a = 10;
public int c = 3;
public void test() {
System.out.println("Derived::test()");
}
public void test2() {
System.out.println("Derived::test2()");
}
public void test(int a) {
System.out.println(a);
}
public void method() {
// super this
System.out.println(this.a);
System.out.println(super.a);
}
public static void main(String[] args) {
Derived derived = new Derived();
derived.method();
}
}

super关键字总结与注意事项

总结:

1. super用来在子类中 指定访问父类成员变量和方法 因为this引用优先访问子类自己的成员

2. super加点号 访问父类成员变量和方法

3. super(..) 访问父类的构造方法

注意事项:

1. super只能在非静态方法中使用

2. 在子类构造方法中调用super(...)初始化父类成员,必须放在第一行

 

super与this 相同点和不同点

相同点:

1. 都是Java中的关键字

2. 只能在类的非静态方法中使用

3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

不同点:

1. this是当前对象的引用  —— super 是从父类继承下的部分成员变量的引用 如图

2.  在非静态成员方法中,this优先访问子类自己的成员变量和属性 如果找不到子类成员 再去访问父类成员 —— super 指定访问父类的成员

3. 在子类构造方法中,this(...)用于调用子类自己的构造方法,super(...)用于调用父类构造方法,两种调用不能同时在构造方法中出现 因为this() super()都需要占用第一行

4.  子类构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,但是this(...)调用用户不写则没有

 

1.5 子类对象如何初始化 ?

首先调用父类构造方法给子类对象中的父类成员进行初始化
 
然后再初始化子类自己的成员
class Animal {
public String name;
public int age;
public void eat() {
System.out.println(name + "正在吃饭");
}
public Animal(String name,int age) {
this.name = name;
this.age = age;
}
}
class Dog extends Animal{
public String color;
public Dog(String name,int age) {
// 在子类自己成员变量初始化前 必须先调用父类构造初始化子类对象中的父类成员
super(name,age);
this.color = "黑色";
}
public static void main(String[] args) {
Dog dog = new Dog("a",1);
System.out.println(dog.name);
}
}

 

为什么自己没写构造,编译器不报错 ?
class Animal {
public String name;
public int age;
public void eat() {
System.out.println(name + "正在吃饭");
}
// 默认生成 Animal构造
/*public Animal() {
}*/
}
class Dog extends Animal{
public String color;
// 默认生成 Dog构造
/*public Dog() {
自动生成 super()
super();
}*/
public static void main(String[] args) {
Dog dog = new Dog();
}
}

 

1.6 继承关系上的执行顺序

父类的静态,子类的静态,父类的实例,父类的构造,子类的实例,子类的构造
class Animal {
public String name;
public int age;
public Animal() {
System.out.println("Animal()");
}
static {
System.out.println("Animal::static{}");
}
{
System.out.println("Animal::{ }");
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Animal(String name, int age)");
}
public void eat() {
System.out.println(this.name+"正在吃.....");
}
}
class Dog extends Animal {
public String color;
public Dog() {
//super();
System.out.println("Dog()");
}
static {
System.out.println("Dog::static{}");
}
{
System.out.println("Dog::{ }");
}
public static void main(String[] args) {
Dog dog = new Dog();
}
}

 

1.7 java继承关系与final修饰类

 

 

2. 访问修饰限定符

class Person implements Cloneable {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException{
// 一定得在子类方法中, 调用protected修饰的父类成员
return super.clone();
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person("a",1);
Person p2 = (Person) person1.clone();
System.out.println(p2.name);
}
}

 

posted @   qyx1  阅读(13)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示