Java基础入门---多态

 

目录

多态

向上转型和动态绑定机制

动态绑定

向下转型和instanceof运算符的应用

instanceof 运算符

抽象类和抽象方法

重点注意:

一个完整准确的抽象类例子

 

内部类

方法内部类

成员内部类

静态内部类

匿名内部类

接口中的内部类

匿名内部类


多态

多态是指,针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法。

Person p = new Student();
p.run(); //无法确定运行时究竟是调用哪个方法

意味着允许不同类的对象对同一消息作曲不同的响应。

分为

  • 编译时多态:设计时多态
  • 运行时多态:程序运行时动态决定调用哪个方法

必要条件:

  • 满足继承关系
  • 父类引用指向子类对象

向上转型和动态绑定机制

1.向上转型的概念:

向上转型又叫自动转型、隐式转型。向上转型是父类引用指向子类实例,也就是子类的对象可以赋值给父类的对象。

如:Animal dog =new Dog(); //Dog类是Animal类的子类

注:向上转型是安全的,因为任何子类都继承并接受了父类的方法。从例子中也可以理解,所有的狗狗都属于狗的父类——动物,这是可行的,但是向下转型则不行,若说所有动物都是狗狗就不成立了。(所以向下转型要通过强制类型转换)

2.向上转型的应用

  1. 当一个子类对象向上转型为父类对象,所能调用的方法会减少,只能调用子类重写父类的方法以及父类派生的方法(如set()、get()方法),而不能调用子类独有的方法。

例如:

对象实例化:

此时,调用方法调用时:

可以调用子类重写父类的方法writing(),但是调用子类独有的show()时就是无效的

2.父类中静态方法是不允许被子类重写的。

多态的实现可以通过向上转型和动态绑定机制来完成,向上转型实现了将子类对象向上转型为父类类型,二动态绑定机制能识别出对象转型前的类型,从而自动调用该类的方法,两者相辅相成。

动态绑定

绑定就是将一个方法调用同一个方法所在的类连接到一起就是绑定。绑定分为静态绑定和动态绑定两种。

  • 静态绑定:在程序运行之前进行绑定(又编译器和链接程序完成的),也叫做前期绑定。
  • 动态绑定:在程序期间又JVM根据对象的类型自动判断应该调用哪个方法,也叫做后期绑定。

静态绑定的例子:

动态绑定的例子

向下转型和instanceof运算符的应用

1.向下转型

2.向下转型后,可以调用子类自己独有的方法。

3.兄弟类之间不能进行强制类型转换。

instanceof 运算符

基本概念

如果左边对象是右边类的实例则返回true,否则返回false。

2.instanceof 的运用

抽象类和抽象方法

1.基本概念:

 

2.抽象类和抽象方法的声明格式

3.抽象类和抽象方法的特点

  1. 抽象类不允许直接实例化,换句话说抽象类不能创建对象,它只能作为其他类的父类。但可以通过向上转型,指向实例化
  2. 抽象方法只有声明,不能有实现,也就是仅有方法头,而没有方法体和操作实现。
    1. 如abstract double area();

4.定义抽象类的意义在于:

 

重点注意:

  • 含有抽象方法的类,只能被定义成抽象类。

  • 抽象类不一定包含抽象方法

 

  • 在抽象类中成员方法可以包括一般方法和抽象方法

  • 抽象类不能被实例化,即使抽象类里不包含抽象方法,这个抽象类也不能创建实例
  • 抽象类的构造方法主要是用于被其子类调用

例子:

  • 一个类继承抽象类后,必须实现其所有抽象方法,否则也是抽象类,不同的子类对父类的抽象方法可以有不同的实现。

  • 即使父类是具体的,但其子类也可以是抽象的,如Object是具体的,但可以创建抽象子类。
  • abstract方法不能用static和private修饰;对于类,不能同时用final和abstract修饰,因为final关键字使得类不可继承,而abstract修饰的类如果不可以继承就没有任何意义,两者放在一起,会起冲突

一个完整准确的抽象类例子

 

内部类

方法内部类

  1. 定义在方法内部,作用范围也在方法内
  2. 和方法内部类成员使用规则一样,class前面不可以添加public、private、protected、static
  3. 类中不能包含静态成员
  4. 类中可以包含final、abstract修饰的成员

成员内部类

  • 内部类在外部使用时,无法直接实例化,需要借由外部类信息才能完成实例化 
  • 内部类的访问修饰符,可以任意,但是访问范围会受到影响
  •    内部类可以直接访问外部类的成员;如果出现同名属性,优先访问内部类中定义的 
  • 可以使用外部类.this.成员的方式,访问外部类中同名的信息
  • 外部类访问内部类信息,需要通过内部类实例,无法直接访问 
  • 内部类编译后.class文件命名:外部类$内部类.class
  • 内部类中是否可以包含与外部类相同方法签名的方法?以及如何调用?
	public class Heart1 {
		int age = 13;
		int temp = 22;

		// public void eat(){....}
		public String beat() {
			eat();
			return Person.this.age + "岁的心脏在跳动";
		}
	}

静态内部类

  1. 静态内部类中,只能直接访问外部类的静态成员,如果需要调用非静态成员,可以通过对象实例 
  2. 静态内部类对象实例时,可以不依赖于外部类对象
  3. 可以通过外部类.内部类.静态成员的方式,访问内部类中的静态成员 
  4. 当内部类属性与外部类属性同名时,默认直接调用内部类中的成员;
  5.  如果需要访问外部类中的静态属性,则可以通过 外部类.属性 的方式; 
  6. 如果需要访问外部类中的非静态属性,则可以通过 new 外部类().属性的方式;
public static class Heart {
		public static int age = 13;
		int temp = 22;

		public static void say() {
			System.out.println("hello");
		}

		public void eat() {
		}

		public String beat() {
			new Person().eat();
			return Person.age + "岁的心脏在跳动";
		}
	}

匿名内部类

  • 匿名内部类没有类型名称、实例对象名称
  • 编译后的文件命名:外部类$数字.class
  • 无法使用private、public、protected、abstract、static修饰
  • 无法编写构造方法,可以添加构造代码块
  • 不能出现静态成员

 

接口中的内部类

我们在实际开发过程中,如果想要创建某些公共代码,使得它们可以被某个接口的所有不同实现所共用,那么接口内部的嵌套类会显得很方便。也就是说,在接口中可以含有内部类。在这里,向大家展示接口中放置普通成员内部类和抽象成员内部类的情况。

匿名内部类

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值