多态性

1、存在继承关系

2、子类要重写父类的方法

3、父类数据类型的引用指向子类对象。

主函数中A a=new B();语句在堆内存中开辟了子类(B)的对象,并把栈内存中的父类(A)的引用指向了这个B对象。

向上转型个人认为是统一格式,也可以认为是花木兰替父从军 可能还有别的花小兰花二兰 她们都替自己的父亲从军但是使用的名字 年龄都是父亲的

引用下网友的分享多态性_第1张图片


对象多态性的本质指的就是子类和父类对象间的互相转换。

现在已经学习完了关于继承的所有概念,但是并不意味着只要使用继承就可以实现代码的全部重用,

而在继承之后又有了个重要的核心概念:多态性;

在java里面对于多态的核心表现主要有以下两点:

·方法的多态性:

  |-方法的重载:同一个方法名称可以根据参数的类型及个数不同调用不同的方法体;

  |-方法的覆写:同一个父类的方法可能根据实例化的子类不同也有不同的是实现;

·对象的多态性(前提:方法覆写):

|-【自动,90%】对象的向上转型:父类  父类对象=(父类 此括号可写可不写)子类实例A a=new B();

|-【强制,1%】对象的向下转型:子类  子类对象=(子类)父类实例;B b=(B) A;

    |- 9%是不进行转型,例如:String;因为String类是给主函数直接操作的如果能转型就乱套了


范例:回顾一个简单程序 

class A{
	public void print() {
		System.out.println("【A】public void print()");
	}
}
class B extends A{
	public void print() {
		System.out.println("【B】public void print()");
	}
}

public class TestDemo {
	public static void main(String[] args) {
		B b=new B();//实例化子类对象
		b.print();//调用被覆写的方法
}}

结果【B】public void print()

于是可以将以上的代码进一步变化,变为向上转型:

范例:实现向上转型

class A{
	public void print() {
		System.out.println("【A】public void print()");
	}
}
class B extends A{
	public void print() {
		System.out.println("【B】public void print()");
	}
}

public class TestDemo {
	public static void main(String[] args) {
		A a=new B();//向上转型
		a.print();
}}
不管是否发生了向上转型,那么其核心的本质还是在于: 你使用的是哪个子类(new在哪里),而后 你调用的方法是否被子类所覆写了。


向下转型指的是将父类对象变成子类对象,但是在这之前需要首先明确一个核心概念,

为什么需要向下转型?

当你需要使用到子类扩充操作的时候就要采用向下转型

范例:向下转型

class A{
	public void print() {
		System.out.println("【A】public void print(){}");
	}
}
class B extends A{
	public void print() {
		System.out.println("【B】public void print(){}");
	}
	public void funB() {//这个方法只有子类偶有
		System.out.println("【B】public void funB(){}");
		
	}
}

public class TestDemo {
	public static void main(String[] args) {
		A a=new B();//向上转型
		//这个时候父类能够调用的方法只能的自己本来定义好的方法
		//并没有B类中的funB()方法,那么只能够进行向下转型处理
		B b=(B) a;//向下转型
		b.funB();
}}

[此概念一般开发中用不到] 但是并不是所有的父类对象都可以向下转型:如果要想进行向下转型操作之前一定要首先发生向上转型,否则在转型时会出现:ClassCastException(类异常转换)

范例:错误的转型

class A{
	public void print() {
		System.out.println("【A】public void print(){}");
	}
}
class B extends A{
	public void print() {
		System.out.println("【B】public void print(){}");
	}
	public void funB() {//这个方法只有子类偶有
		System.out.println("【B】public void funB(){}");
		
	}
}

public class TestDemo {
	public static void main(String[] args) {
		A a=new A();//实例化父类对象
		B b=(B) a;//强制转换
}}

我们可以把父类A当成一个不知道有自己孩子的父亲 而子类B身上有父亲的特征所以他清楚谁是他父亲

正确的做法应该是:先有上然后再有下

public class TestDemo {
	public static void main(String[] args) {
		
		A a1=new B();
		B b=(B) a1;//强制转换
		b.funB();
}}

但是现在就有一个问题出现了,如果向下转型可能存在有隐患,那么如何转型才靠谱呢?

最好的做法是先进行判断,而后再进行转型,那么就可以依靠instanceof关键字来实现了,此关键字的使用语法如下:

·   子类对象   instanceof   类,返回的是boolean型数据;

范例:观察instanceof关键字的使用 

引用A B类
public class TestDemo {
	public static void main(String[] args) {
	A a=new B();//实例化父类对象
System.out.println(a instanceof A);
System.out.println(a instanceof B);
	}}

通过子类对象是实例化的父类,所以子类对象实例化时一定会同时实例化父类对象

所以代码的执行结果是

true true

但是当我把 new B();改成new A();时

结果为 

true false 

再观察入如下代码  

public class TestDemo {
	public static void main(String[] args) {
	A a=new B();//实例化父类对象
	
System.out.println(a instanceof A);
System.out.println(a instanceof B);
//以后对于子类的特殊操作尽量慎用
if(a instanceof B) {//避免ClassCastException问题 
	B b=(B)a;
	b.funB();
}
	}}

虽然清楚了一系列的操作关系,可是还必须思考,这种转换有什么意义?

范例:要求定义一个方法,而这个方法而可以接受Person类的所有子类实例,并调用Person类方法:

class Person{
	public void takeoff() {
		System.out.println("要迟到了。。。");
	}
}
class Student extends Person{
	public void takeoff() {
		System.out.println("又要迟到了....");
	}
}
class Teacher extends Person{
	public void takeoff() {
		System.out.println("哎,又要迟到了");
	}
}

public class TestDemo {

	public static void main(String[] args) {
		in(new Student());
		in(new Teacher());
//不管传入进来的是学生还是老师 都是会迟到,这是对象多态性的好处
	}
	public static void in(Person per) {//对象多态性
		per.takeoff();
	} 
	//如果不使用对象多态性就要重载多个方法很复杂 
	/*例如
	 * public static void in(Student stu){
	 * stu.takeoff();}
	 * public static void in(Teacher tea)}{
	 * tea.takeoff();}
	 * */

}  

通过以上的分析就可以清楚,对象的向上转型又一个最为核心的用处;操作参数统一


1.对象多态性实现的核心在于方法的覆写;

2.通过对象的向上转型可以实现接收参数的统一,而向下转型可以实现子类扩充方法的调用(一般不操作向下转型 了解即可  ,不过也挺重要的 );

3.两个没有关系的类对象,是不能够转型的,一定会发现生ClassCastException,所以向下转型是存在安全隐患的。

最后再看一个向上转型加深印象

class Person{
	public void takeoff() {
		System.out.println(
				"要迟到了。。。");
	}
}
class Student extends Person{
	public void takeoff() {
		System.out.println("又要迟到了....");
	}
}
class Teacher extends Person{
	public void takeoff() {
		System.out.println("哎,又要迟到了");
	}
}
public class TestDemo {

	public static void main(String[] args) {
		Student stu=new Student();//先实例化子类对象
		Person per= (Person) stu;//向上转型     (Person)可写可不写 
		per.takeoff();//父类调用子类方法
	
		
		Student stu1=(Student) per;//向下转型 基本用不到
		per.takeoff();
	}

}//又要迟到了....  
又要迟到了....             


你可能感兴趣的:(设计辅助概念)