java多态性详解

什么是多态

  多态是java中面向对象的四个基本特性之一,是面向对象程序设计中代码重用的一个重要机制,它表示了同一个操作作用在不同对象时,会有不同的语义,进而产生不同的结果。

在这里插入图片描述

多态的表现形式

  • 编译时多态:方法的重载,重载指的是同一个类中有多个同名方法,当方法的参数不同时(参数的类型和个数的不同),编译时就可以确定调用哪个方法,是同一个类中多态性的表现方式。
  • 运行时多态:方法的重写,java中子类可以重写父类的方法,同样的方法在父类与子类中有着不同的表现形式。父类的引用可以指向子类对象,程序调用的方法在运行期才动态绑定,运行时才可以确定调用哪个方法,因此称之为运行时多态,是父类与子类之间多态性的表现方式。(不同类实现同一个接口也属于这种情况)。

多态存在的必要性

  • 要有继承
  • 要有重写
  • 父类引用子类对象

多态的作用

  • 代码变的更加灵活,在调用方法时,根据传入参数的不同就可以执行不同的方法,从而得到想要的结果。
  • 代码拓展性变得更好,并可以对所有类的对象进行通用处理。

对象的多态性

  • 向上转型:父类 父类对象 = 子类实例
package test;

public class Father {
	
public void print() {
	System.out.println("我是father");
}
public static void main(String[] args) {
	Father p1 = new Father();
	Father p2 = new son();//向上转型
	son s = new son();
	p1.print();
	p2.print();
	s.print();
	s.play();
}
}

class son extends Father{

	@Override
	public void print() {
		System.out.println("我是son");
	}
	public void play() {
		System.out.println("我是son,我能够玩耍");
	}
	
}

运行截图:
java多态性详解_第1张图片
从运行结果上可以看出,在实例化子类对象时,如果父类的实例引用了子类的对象(多态),例如:父类 实例 = new 子类(),那么该引用在调用父类的方法时遵循以下原则:

  • 该实例 可以调用父类中特有的方法。(该方法未被子类重写)
  • 该实例如果调用父类中的方法,若该方法被子类重写,则一定调用的是在子类中重写后的该方法。
  • 该实例不可以调用父类中没有的方法。(该方法子类特有),如p1不能调用子类的play()方法。
  • 父类的属性 不能被子类覆盖。

此外向上转型还可以实现参数统一化:

//参数统一化
class Person{
    public void  print() {
       System.out.println("1.Person类的print方法"); 
    }
}
class Student extends Person{
    public void print(){
        System.out.println("2.Student类的print方法");
    }
}
class Worker extends Person{
    public void print(){
        System.out.println("3.Worker类的Print方法");
    }
}
public class Text6{
    public static void main(String[] args){
        fun(new Person());//Person per = new Person();
        fun(new Student());//Person per = new Student();//向上转型   Student类 转为 Person类
        fun(new Worker());//Person per = new Worker();//向上转型     Worker 类 转为 Person类
    }
    public static void fun(Person per){
        per.print();
    }

}
//运行结果:
//1.Person类的print方法
//2.Student类的print方法
//3.Worker类的Print方法

  • 向下转型,强制转型 子类 子类对象 = (子类)父类实例
    向下转型可以实现子类扩充方法调用(有安全隐患,一般不操作!);
//向下转型 将父类对象转为子类
class Person{
    public void print(){
        System.out.println("1.我是爸爸!");
    }
}
class Student extends Person{
    public void print(){
        System.out.println("2.我是儿砸!");
    }
    public void fun(){
        System.out.println("3.只有儿砸有!");
    }
}
public class Text8{
    public static void main(String[] args){
      Person per = new Student();//向上转型 
      per.print();//能够调用的只有父类已定义好的
      
      Student stu = (Student) per;//向下转型
      stu.fun();//
    }
}

父类需要子类扩充的属性或方法时需要向下转型;并不是所有父类都可以向下转型,如果想要向下转型之前,一定要首先发生向上转型过程,否则会出现ClassCastException(类型转换异常 属于运行时异常)。两个没有关系的类是不能发生转型的,一定会产生ClassCastException.
解释:就是一个父类对象能够转成子类对象一定得是new一个子类实例得到的,这样才能转成子类对象,如果是一个new一个父类实例转成子类就会报错。看下面这个例子:

package test;

public class Father {
public void print() {
	System.out.println("我是father");
	
}
public static void main(String[] args) {
	Father p1 = new Father();
	Father p2 = new son();
	try {
	son s = (son)p1;
	s.play();
	System.out.println();
	}catch(ClassCastException e) {
		System.err.println("p1转成子类失败");
	}
	son s2 = (son)p2;
	s2.play();
}
}

class son extends Father{
	@Override
	public void print() {
		System.out.println("我是son");
	}
	public void play() {
		System.out.println("我是son,我能够玩耍");
	}
	
}

运行结果:
java多态性详解_第2张图片
如何判断当前对象知否指向目标类呐?使用instanceof类,他的作用就是检查当前对象是否属于目标类。

package test;

public class Father {
public void print() {
	System.out.println("我是father");
	
}
public static void main(String[] args) {
	Father p1 = new Father();
	Father p2 = new son();
	System.out.println("p1是否指向Father:"+(p1 instanceof Father));
	System.out.println("p1是否指向sonFather:"+(p1 instanceof son));
	System.out.println("p2是否指向Father:"+(p2 instanceof Father));
	System.out.println("p2是否指向son:"+(p2 instanceof son));
}
}
class son extends Father{
	@Override
	public void print() {
		System.out.println("我是son");
	}
	public void play() {
		System.out.println("我是son,我能够玩耍");
	}
	
}

运行截图:
java多态性详解_第3张图片

你可能感兴趣的:(java)