深入理解Java中的继承与多态(包括向上、向下转型)

本文详细解读了Java中的继承机制,包括构造方法的调用、访问修饰符、this与super的区别,以及多态的概念、重载与重写。通过实例演示了向上转型和向下转型,并介绍了如何使用实例化、传参和返回值实现。最后讨论了关键字`instanceof`在向下转型中的作用。

继承

  • 语法结构:class 子类名称 extends 父类名称 { }
  • 子类继承了父类除构造方法以外所有的。例如:
class Animals{
	String name;
	int age;
	void eat(){
		System.out.println("Animals:eat()");
	}
}
class cat extends Animals{
}
//cat作为animals的子类,就继承了父类的name、age属性和eat()方法。

注:如果父类中有私有的属性或行为,子类也会继承,只是不能去访问。

  • 父类中默认使用无参构造方法,如果其中定义了有参的构造方法,则子类在构造时,要先帮父类进行构造,然后才调用自己的。例如:
class Animals{
	public Animals(String name) {
		this.name = name;
		System.out.println("Animals");
	}
}
class cat extends Animals{
	public cat(String name) {
		super(name);//显示调用
		System.out.println("cat");
	}
}
//如果我们实例化一个cat对象,则会先输出Animals,再输出cat.

注:super(name);语句为显示调用,调用的是父类的构造函数

  • Java中的4种访问修饰限定符
No范围privatedefaultprotectedpublic
1同一包中的同一类####
2同一包中的不同类###
3不同包中的子类##
4不同包中的非子类#

注:default修饰符,为默认修饰符,也称包访问权限。
final修饰的常量只能在定义的时候,被初始化一次,不能再被修改;
final修饰的类不能被继承;
final修饰的方法为密封方法(后面会提及)。

  • this和super的区别
    this:是对当前对象的引用
    1.this( ); //调用本类中的其他构造方法
    2.this.data; //访问当前类当中的属性
    3.this.func( ); //调用本类中的其他成员方法
    super:代表父类对象的引用
    1.super( ); //调用父类的构造方法
    2.super.data; //访问父类的属性
    3.super.func( ); //访问父类的成员方法

注:对于多层继承,我们一般只写到第三层。

多态

  • 首先,我们先讲一下什么是多态?
    多态就是多种形态,具体来讲就是:去完成某一行为时,当不同的对象去完成时会产生不同的状态。(即,在不同的继承关系的类对象中,调用同一函数会产生不同的行为

  • 然后,我们再讲一下两个概念:重载和重写(覆盖)。

方法名参数列表(类型和个数)返回值出现的地方关键词
重载相同不同不做要求同一个类中overlord
重写相同相同相同在继承关系中override

注:1.普通方法可以重写,但是static 修饰的静态方法不能被重写。
2.被final修饰的方法不能被重写。
3.被重写的方法,访问修饰限定符一定不能是private的。
4.被重写的方法,子类当中的访问修饰符限定要大于等于父类的访问修饰符限定。

  • 向上转型:把子类对象赋值给父类引用后,该引用只能够访问父类的属性和方法。发生向上转型的时机有三种:直接赋值、传参、返回值。例如:
class Animals{
	String name;
	int age;
	void eat(){
		System.out.println("Animals:eat()");
	}
}
class cat extends Animals{
	String color;
	void eat(){
		System.out.println("Cat:eat()");
	}
}

public class demo_1 {
	public static void main(String[] args){
	//1.直接赋值
		Animals animal = new cat();
		//animal.color = "gray"; //color为cat中的属性,不能被调用
		animal.name = "球球";
		animal.age = 1;
}

public class demo_1 {
	//2.传参
	public static void func(Animals animal){
		animal.eat();
	}
	public static void main1(String[] args){
		Cat cat = new Cat("豆豆");
		func(cat);
	}
}

public class demo_1 {
	//3.返回值
	public static Animals func2() {
		Cat cat = new Cat("豆豆");
		return cat;
	}
	public static void main(String[] args){
		Animals animals = func2();
		animals.eat();
	}
}

特别注意:当我们使用父类引用子类对象时,如果通过父类引用调用同名的覆盖方法,此时就会发生运行时绑定
即,在编译时:父类引用调用父类的构造方法—>调用子类的构造方法—>调用父类中的同名方法;
但是在运行时,调用的实际为子类中的同名方法。
比如上述例子中,如果父类引用调用同名方法eat( ),则会输出结果Cat:eat( )
PS:javac -c 类名:用来打印反汇编代码。

  • 向下转型:把父类对象赋值给子类引用,向下转型过程中容易出现类型转换异常,通常我们用关键字instanceof来帮助解决。例如:
	public static void main(String[] args){
		Animals animals = new Cat("仔仔");
		if(animals instanceof Bird){  //看animals是不是Bird的一个实例化对象
			Bird bird = (Bird)animals;
			bird.fly();
		}
		else{
			System.out.println("false!!!");
		}
	}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值