Java学习笔记12继承(一)_20200410

本文详细介绍了Java中的继承概念,包括继承的特性、方法重写规则,并通过多个实例进行演示,如子类隐藏超类字段、构造器使用、访问权限等,帮助读者深入理解Java的继承机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第12章 继承

01 练习

02 继承

Java中通过继承一个类,来继承此类的所有功能。
Java中的每一个类都继承于Object,当创建一个类时,会自动的继承Object类的所有方法。

例一

package com.day10;

class Foo {
	
}

public class Day102 {
	public static void main(String[] args) {
		Foo f = new Foo();
		//toSring方法继承于Object
		System.out.println(f.toString());
		System.out.println(f.hashCode());
	}
}

在这里插入图片描述


tips:
Ctrl + Shift + T --> open type
Object:
在这里插入图片描述
在这里插入图片描述
按Ctrl + o
在这里插入图片描述
找到toString方法
在这里插入图片描述
在这里插入图片描述
hashCode
在这里插入图片描述
在这里插入图片描述


例二

instanceof关键字用于判断一个对象是否是这个类型

在这里插入图片描述

例三

package com.day10;

class Foo {
	
}

public class Day102 {
	public static void main(String[] args) {
		Foo f = new Foo();
		//toSring方法继承于Object
		System.out.println(f.toString());
		System.out.println(f.hashCode());
		
//		//instanceof关键字用于判断一个对象是否是这个类型
//		if(f instanceof Object) {
//			System.out.println("Foo 继承于Ojbect");
//		}
		
		//f是Object类的实例
		System.out.println(f instanceof Object); //true
		//f是Foo类的实例
		System.out.println(f instanceof Foo); //true
				
	}
}


-------Console--------------
com.day10.Foo@1db9742
31168322
true
true

在这里插入图片描述

例四

在这里插入图片描述
在这里插入图片描述

package com.day10;

class Actor {
	public void act() {
		System.out.println("act");
	}
}
//Hero继承于Actor
class Hero extends Actor {
	public void fight() {
		System.out.println("fight");
	}
}


public class Day103 {
	public static void main(String[] args) {
		Hero h = new Hero();
		//act方法继承于Actor
		h.act();
		//fight方法继承于自己
		h.fight();
	}
}



-------Console--------
act
fight

在这里插入图片描述

例五

Object类位于java.lang包中,它定义和实现了所有类的通用功能。
例子:

package com.day10;

//演员
class Actor {
	public void act() {
		System.out.println("act");
	}
}
//英雄
//Hero继承于Actor
class Hero extends Actor {
	public void fight() {
		System.out.println("fight");
	}
}
//喜剧演员
class Comedian extends Actor {
	public void performComedy(){
		System.out.println("comedy");
		
	}
}


public class Day103 {
	public static void main(String[] args) {
		Hero h = new Hero();
		//act方法继承于Actor
		h.act();
		//fight方法继承于自己
		h.fight();		
		System.out.println(h instanceof Hero);  //true
		System.out.println(h instanceof Actor); //true
		System.out.println(h instanceof Object);//true
		
		Comedian c = new Comedian();
		//act方法继承于Actor
		c.act();
		c.performComedy();
		System.out.println(c instanceof Comedian);//true
		System.out.println(c instanceof Actor); //true
		System.out.println(c instanceof Object); //true
				
	}
}


------Console-----
act
fight
true
true
true
act
comedy
true
true
true

在这里插入图片描述

例六

一个子类可以继承超类的所有public和protected成员(非静态成员,静态成员不考虑继承问题),不管子类在哪个包。

如果子类和超类在同一包下,它还可以继承其超类默认访问权限的成员。

private成员不能被继承。


操作步骤,实验:

在同一个包下(如:com.day10)中,
创建Animal类,Dog类,Day104主类,
如下:

  1. Animal类
package com.day10;

public class Animal {
	private int  privateV;
	protected int protectedV;
	public int publicV;
	int defaultV;
	
}

在这里插入图片描述
2) Dog类

package com.day10;

public class Dog extends Animal {
	

}

在这里插入图片描述
3) Day104主类

package com.day10;

public class Day104 {
	public static void main(String[] args) {
		Dog d = new Dog();
		
//		System.out.println(d.privateV);//编译错误
		System.out.println(d.protectedV);
		System.out.println(d.publicV);
		System.out.println(d.defaultV);
		
	}

}

在这里插入图片描述
***测试:
新建一个包(com.day101),把Dog类移动到其内,
此时,d.defaultV 报错。
在这里插入图片描述

***tips;
复制一行
Ctrl + Alt + up/down

例七

子类可以声明和超类同名的字段,这将导致隐藏其超类的字段。可以使用super关键字来访问超类的字段。

(超类的字段并不是没有了,而是被隐藏了)

1)Animal类

package com.day10;

public class Animal {
	private int privateV;
	protected int protectedV;
	public int publicV;
	int defaultV;
}
}

在这里插入图片描述
2) Dog类

package com.day10;

public class Dog extends Animal {
	public int publicV;

	public Dog(int publicV) {
		this.publicV = publicV;
		System.out.println(this.publicV);// 10
		System.out.println(super.publicV);// 0
	}
}

在这里插入图片描述

  1. 主类
package com.day10;

public class Day104 {
	public static void main(String[] args) {

	Dog d = new Dog(10);
	// System.out.println(d.publicV);
	}
}

在这里插入图片描述

例八

子类可以声明和超类同名的字段,这将导致隐藏其超类的字段。可以使用super关键字来访问超类的字段。
注意:
(1)隐藏不是覆盖,隐藏只是藏起来了。
(2)简单理解,super就是指的超类的对象。
在创建一个子类的对象的时候,首先会创建一个超类的对象。即,没有父,哪有子呀。

package com.day10;

public class Animal {
	private int privateV;
	protected int protectedV;
	public int publicV;
	int defaultV;
}

在这里插入图片描述
2)

package com.day10;

public class Dog extends Animal {
	public int publicV;

	public Dog(int publicV) {
		this.publicV = publicV;
//		System.out.println(this.publicV);// 10
//		System.out.println(super.publicV);// 0
	}
}

在这里插入图片描述
3)

package com.day10;

public class Day104 {
	public static void main(String[] args) {
 		Dog d = new Dog(10);
		System.out.println(d.publicV); //10
	}
}

在这里插入图片描述

例九

例9.1

接上代码继续
1)给Animal一个构造器

package com.day10;

public class Animal {
	private int privateV;
	protected int protectedV;
	public int publicV;
	int defaultV;

	public Animal() {
		System.out.println("Animal");

	}
}

在这里插入图片描述
在这里插入图片描述
2) Dog.java, Day104.java 代码不变;运行。
结果:
首先调用超类的构造器。

在这里插入图片描述

例9.2
  1. Animal.java 不变
package com.day10;

public class Animal {
	private int privateV;
	protected int protectedV;
	public int publicV;
	int defaultV;

	public Animal() {
		System.out.println("Animal");

	}
}

在这里插入图片描述
2)给Dog.java中添加代码:

Dog d = new Dog(10);

如下:

package com.day10;

public class Dog extends Animal {
	public int publicV;

	public Dog(int publicV) {
		System.out.println("Dog");
		this.publicV = publicV;
	}
}

在这里插入图片描述
3 ) 主函数不变。运行。
Animal
Dog
10

package com.day10;

public class Day104 {
	public static void main(String[] args) {
	
		Dog d = new Dog(10); //调Dog的构造器
		System.out.println(d.publicV); //10
	}
}

在这里插入图片描述

例十

构造器不是类的成员,因此无法被继承,但是子类可以调用超类的构造器。
1) Animal.java
给一个带参的构造器
Alt + Shift + s --> Generate Constructor using Fields
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

删掉super();
在这里插入图片描述

再加一个无参的构造器
Alt + shift + s -->Generate Constructor from Superclass…
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  1. 子类 Dog.java
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

例十一

构造器不是类的成员,因此无法被继承,但是子类可以调用超类的构造器。

例11.1

1) Animal.java

package com.day10;

public class Animal {
	private int privateV;
	protected int protectedV;
	public int publicV;
	int defaultV;
	
	public Animal() {
		System.out.println("Animal无参构造器");
	}

	public Animal(int privateV, int protectedV, int publicV, int defaultV) {
		System.out.println("Animal有参构造器");
		this.privateV = privateV;
		this.protectedV = protectedV;
		this.publicV = publicV;
		this.defaultV = defaultV;
	}
		
}

在这里插入图片描述
2) Dog.java

package com.day10;

public class Dog extends Animal {
	public int publicV;
	
	public Dog(int publicV) {
		System.out.println("Dog");
		this.publicV = publicV;
	}
}

在这里插入图片描述
3) 主方法

package com.day10;

public class Day104 {
	public static void main(String[] args) {

		Dog d = new Dog(10); //调Dog的构造器
		System.out.println(d.publicV); //10
	}
}

在这里插入图片描述

例11.2
  1. Animal.java 代码不变
package com.day10;

public class Animal {
	private int privateV;
	protected int protectedV;
	public int publicV;
	int defaultV;
	
	public Animal() {
		System.out.println("Animal无参构造器");
	}

	public Animal(int privateV, int protectedV, int publicV, int defaultV) {
		System.out.println("Animal有参构造器");
		this.privateV = privateV;
		this.protectedV = protectedV;
		this.publicV = publicV;
		this.defaultV = defaultV;
	}
		
}

在这里插入图片描述

2 ) Dog.java

package com.day10;

public class Dog extends Animal {
	public int publicV;
	
	public Dog(int publicV) {
//		super();//调用超类无参构造器
		super(1,2,3,4); //调用超类有参构造器
		System.out.println("Dog");
		this.publicV = publicV;

	}
}

在这里插入图片描述

  1. 主方法
package com.day10;

public class Day104 {
	public static void main(String[] args) {

		Dog d = new Dog(10); //调Dog的构造器
		System.out.println(d.publicV); //10
	}
}

在这里插入图片描述

例十二

子类并不会继承超类的私有成员,但是子类可以调用超类的public或protected方法来访问超类的私有成员。

1) Animal.java

package com.day10;

public class Animal {
	private int privateV;
	protected int protectedV;
	public int publicV;
	int defaultV;
		
	public int getPrivateV() {
		return privateV;
	}

	public void setPrivateV(int privateV) {
		this.privateV = privateV;
	}

	public Animal() {
		System.out.println("Animal无参构造器");
	}

	public Animal(int privateV, int protectedV, int publicV, int defaultV) {
		System.out.println("Animal有参构造器");
		this.privateV = privateV;
		this.protectedV = protectedV;
		this.publicV = publicV;
		this.defaultV = defaultV;
	}
		
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  1. Dog.java
package com.day10;

public class Dog extends Animal {
	public int publicV;
	
	public Dog(int publicV) {
//		super();//调用超类无参构造器
		super(1,2,3,4); //调用超类有参构造器
		System.out.println("Dog");
		this.publicV = publicV;
		
		System.out.println(super.getPrivateV()); //1
		
	}
}

在这里插入图片描述
在这里插入图片描述
不能访问私有变量,可以通过访问公开的方法来访问私有变量。

  1. 主方法
package com.day10;

public class Day104 {
	public static void main(String[] args) {

		Dog d = new Dog(10); //调Dog的构造器
		System.out.println(d.publicV); //10
	}
}

在这里插入图片描述

例十三

父类型的变量可以引用子类型的对象

13.1

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

13.2

由于Object类是所有类的超类,因此Object类的变量可以引用任何类的实例。

在这里插入图片描述

例十四

Java不允许多继承。

小结

一个子类可以继承超类的所有public和protected成员(非静态成员,静态成员不考虑继承问题),不管子类在哪个包。

如果子类和超类在同一包下,它还可以继承其超类默认访问权限的成员。

private成员不能被继承。

子类可以声明和超类同名的字段,这将导致隐藏其超类的字段。可以使用superd键字来访问超类的字段。

构造器不是类的成员,因此无法被继承,但是子类可以调用超类的构造器。

子类并不会继承超类的私有成员,但是子类可以调用超类的public或protected方法来访问超类的私有成员。

父类型的变量可以引用子类型的对象

由于Object类是所有类的超类,因此Object类的变量可以引用任何类的实例。

Java不允许多继承。

03 方法重写

子类可以创建和超类拥(REH)有同样签名的方法(方法签名包括方法名和参数列表),这叫做方法重写。

03.1

例1:

package com.day101;

class Animal {
	public String say() {
		return "不知道";
	}
}

class Cat extends Animal {
	public String say() {
		return "喵喵喵";
	}
}

public class Day107 {
	public static void main(String[] args) {
		Cat c = new Cat();
		System.out.println(c.say());//喵喵喵
	}
}

在这里插入图片描述

例2:

package com.day101;

class Animal {
	public String say() {
		return "不知道";
	}
}

class Cat extends Animal {
//	public String say() {
//		return "喵喵喵";
//	}
}

public class Day107 {
	public static void main(String[] args) {
		Cat c = new Cat();
		System.out.println(c.say());
	}
}

在这里插入图片描述

例3.3

子类重写的方法不能比超类拥有更小的访问权限。
如:在这里插入图片描述

03.2 方法重写的规则

方法重写的规则:
1.子类只能重写它可见的方法。
被标记为static和final的方法不能被重写。
在这里插入图片描述final方法不允许被重写

  1. 在重写的方法中可以使用super关键字来调用其超类的方法。
package com.day101;

class Animal {
	public  String say() {
		return "不知道";
	}
}

class Cat extends Animal {
	public String say() {
		System.out.println(super.say());// 不知道
		return "喵喵喵";
	}
}

public class Day107 {
	public static void main(String[] args) {
		Cat c = new Cat();
		System.out.println(c.say());//喵喵喵
	}
}

在这里插入图片描述

  1. 重写的方法要比超类的返回值类型小
    (1) 例一:
package com.day101;

class Animal {
	public  String say() {
		return "不知道";
	}
	public int getAge(){
		return 1;
	}
}

class Cat extends Animal {
	public String say() {
		System.out.println(super.say());// 不知道
		return "喵喵喵";
	}

	public int getAge() {
		return 1;
	}
}

public class Day107 {
	public static void main(String[] args) {
		Cat c = new Cat();//创建两个对象
		System.out.println(c.say());//喵喵喵
		Cat c1 = new Cat();//创建两个对象
		
	}
}

在这里插入图片描述
( 2 ) 例二
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
(3)***思考:
使用short,也报错。
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值