Java 基础学习之对象的多态性

1. 基本概念

1.1 在 Java 中面向对象的多态性主要有以下两种体现方式:

  1. 方法的重载与覆写。
  2. 对象的多态性。
  3. 而对象的多态性主要又分为以下两种类型:
    (1)向上转型:子类对象 —> 父类对象
    (2)向下转型:父类对象 —> 子类对象
    对于向上转型,程序会自动完成,而对于向下转型时,必须明确的指明要转型的子类类型。格式:
对象向上转型:父类  父类对象 = 子类实例;
对象向下转型:子类  子类对象 = (子类)父类实例;

1.2 重载相关概念

  1. 方法重载就是方法名称相同,但参数类型(参数列表,即顺序不同)和参数个数不同(返回值类型可不同),通过传递参数个数和类型不同完成不同功能的方法调用,但是返回值类型不作为是否重载的标准,可以修改可见性。【方法名称相同,参数个数、次序、类型不同;重载对返回值没有要求,可以相同,也可以不同】
  2. 方法的参数类型和个数完全相同,但方法的返回值类型不同,这样的程序编译不通过,所以不是方法重载。
  3. 提示: System.out.println( ) 方法也属于重载方法。该方法可以打印数字、小数、字符、布尔类型等各种各样数据。

1.3 覆写相关概念

  1. 所谓的方法覆写就是指子类定义了与父类中同名方法,但是在方法覆写时必须考虑到权限,即被子类覆写的方法不能拥有比父类更加严格的访问权限。(private < default < public)。
  2. 如果在父类中使用 public 定义的方法,子类的访问权限必须是 pulblic,否则程序无法编译。
  3. 只在子类中扩大访问权限,方法内容不做改变也属于覆写。
  4. 方法覆写时从 private 变为 default 不是方法的覆写。
  5. 方法的重写需要满足:三同一大一小(方法名、返回值类型、形参相同;访问权限>=重写前;抛出异常<=重写前)

1.4 方法的重载与覆写的区别

序号区别点重载覆写
1单词OverloadingOverriding
2定义方法名称相同,参数类型和参数个数不同方法名称、参数类型、参数个数、返回值类型完全同
3定义对权限没有要求被覆写的方法不能拥有更严格的访问权限
4范围发生在一个类中发生在继承类中

1.5 对象向上转型和向下转型代码实例

对象向上转型实例代码:
package self.learn.up;

public class A {
	public void fun1() {
		System.out.println("A --> public void fun1(){}");
	}
	public void fun2() {
		this.fun1();
	}
}

package self.learn.up;

public class B extends A {
	public void fun1() {                  // 覆写父类中的 fun1()
		System.out.println("B --> public void fun1(){}");
	}
	public void fun3() {                 // 子类自己定义的方法
		System.out.println("B --> public void fun3(){}");
	}
}
package self.learn.up;

public class PolDemo1 {

	public static void main(String[] args) {
		B b = new B();        // 定义子类实列化对象
		A a = b;              // 发生了向上转型 子类 ---> 父类
		a.fun1();
	}
}
运行结果截图:

在这里插入图片描述
   由结果可知,此时虽然使用的是父类对象调用了 fun1() 方法,但实际上是调用被子类覆写过的方法,也就是说,==如果对象发生了向上转型关系,所调用的肯定是被子类覆写过的方法。==但是此时一定要注意,此时 a 对象是无法调用 B 类中的 fun3( ) 方法,因为此方法只在子类定义,而没有在父类定义,如果要想调用子类定义的其它方法,肯定要用子类实例,所以此时可以将对象向下转型。

对象向下转型实例代码:
package self.learn.up;

public class A {
	public void fun1() {
		System.out.println("A --> public void fun1(){}");
	}
	public void fun2() {
		this.fun1();
	}
}

package self.learn.up;

public class B extends A {
	public void fun1() {                  // 覆写父类中的 fun1()
		System.out.println("B --> public void fun1(){}");
	}
	public void fun3() {                 // 子类自己定义的方法
		System.out.println("B --> public void fun3(){}");
	}
}
package self.learn.up;

public class PolDemo1 {

	public static void main(String[] args) {
		A a = new B();        // 发生了向上转型 子类 ---> 父类
		B b = (B)a;           // 此时发生了向下转型关系
		b.fun1();             // 调用被覆写过的方法
		b.fun2();             // 调用父类方法
		b.fun3();             // 调用子类自己的方法		
	}
}

运行结果截图:

在这里插入图片描述
   从结果中可以发现,如果想调用子类自己的方法,则只能用子类声明对象,另外在子类中调用了父类中继承而来的 fun() 方法,fun2() 方法要调用 fun1() 方法,由于此时 fun1() 方法已经被子类所覆写,所以此时调用的是被子类覆写过的方法。 在进行向下转型之前,必须首先向上转型,否则将出现对象转换异常。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值