Java的多态

Posted WZ_BeiHang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java的多态相关的知识,希望对你有一定的参考价值。

Java的多态

多态的概念(简而言之一句话:父类的引用,指向子类的对象。Parent p = new Child();)

多态:实际类型确定,引用类型不确定,表现出来了多种状态,就是多态。

调用相同名字的方法,具体采用的是哪个方法,根据发送对象的不同而采用多种不同的行为方式,就是多态。

多态使程序更灵活。

比如:父类是Person,子类是Student,当:

Student s1 = new Student();

Person s2 = new Student(); //父类的引用指向子类

Object s3 = new Student(); //父类的引用指向子类

即:一个对象的实际类型是确定的,就是Student

但是,引用类型有指向Student的,有指向Person的,有指向Object的,引用类型不同。所以表现出了多种状态。

多态的注意事项

  1. 多态是方法的多态,属性没有多态。

  2. 父类和子类之间才有多态。当没有父子关系时,提示ClassCastExpection!异常。

  3. 存在条件:有继承关系,方法需要重写,父类引用指向子类对象(反过来不行,只能父类指向子类)。Father f1 = new Son();

多态的方法调用

  1. 一个对象的实际类型是确定的

1.1. new Student();

1.2. new Person();

  1. 可以指向的引用类型不确定:父类的引用可以指向子类

  1. Student(子类)能调用的方法是自己的,或者继承父类的

  2. Person(父类)和Object(父类)可以指向子类,但不能调用子类独有的方法。

         5. 第一句话:换句话说,对象能执行哪些方法,看对象左边的类型,与右边的关系不大。

             第二句话:对象执行的某一方法是类里面的方法,看等号右边,与前面相反。

             解释下5中第一句话:子类有一个方法,父类没这个方法,父类 对象 = new 子类();则,该对象不能调用父类没有,子类有的这个方法。否则报错:

下面这个看等号左边

             解释下5中第二句话:子类有一个方法,父类没这个方法,父类 对象 = new 子类();则,该对象不能调用父类没有,子类有的这个方法。否则报错:

下面这个看等号右边

总结一句话:有没有方法看等号左边,执行哪个方法看等号右边(是否重写)

instanceof关键字

用来判断一个对象是什么类型,判断是否有父子关系。

System.out.println(X instanceof Y);  
  1. 这句话是否能编译通过:取决于X和Y之间是否存在父子关系。

  2. 这句话输出是true还是false:取决于X指向的实际类型,是不是Y的子类型。

Y X = new X指向的实际类型;
System.out.println(X instanceof Y);  

举例:

//Object > String

//Object > Person > Teacher

//Object > Person > Student

Object object = new Student();
System.out.println(object instanceof Student);     //true
System.out.println(object instanceof Person);      //true
System.out.println(object instanceof Object);      //true
System.out.println(object instanceof Teacher);     //false
System.out.println(object instanceof String);      //false

 

Person person = new Student();
System.out.println(person instanceof Student);     //true
System.out.println(person instanceof Person);      //true
System.out.println(person instanceof Object);      //true
System.out.println(person instanceof Teacher);     //false
//System.out.println(person instanceof String);   //编译报错,因为Person和String无父子关系

 

Student student = new Student();
System.out.println(student instanceof Student);     //true
System.out.println(student instanceof Person);      //true
System.out.println(student instanceof Object);      //true
//System.out.println(student instanceof Teacher); //编译报错,Student和Teacher无父子关系  
//System.out.println(person instanceof String);   //编译报错,Person和String无父子关系

类型之间的强制转换

多态的时候(父类的引用,指向子类的对象,Parent p = new Child();),涉及强制转换。

  1. 把子类对象转换成父类:即向上转换,不需要强制转换,可以之间转换过去。

  2. 把父类对象转换成子类:即向下转换,需要强制转换,这时可能会丢失一些方法

  3. 强制转换的目的是,使用当前现场的类,方便方法调用,减少重复代码,简洁。

Person是父类,Student是子类:Person obj = new Student();

obj调用子类Student的方法时,需要:((Student) person).

1、main()方法

package com.WZ.Demo.Application;
import com.WZ.Demo.ClassSet.Person;
import com.WZ.Demo.ClassSet.Student;

public class Application {
   public static void main(String[] args) {
       Person  person = new Student();
       Student student = new Student();
       //从下往上转,不需要强制转换,自动转
       student.sMethod();            //Student1
       student.sStaticMethod();      //Student2
       student.pMethod();            //Person1
       student.pStaticMethod();      //Person2
       //从上往下转,需要强制转换
      ((Student) person).sMethod();       //Student1
      ((Student) person).sStaticMethod(); //Student2
       person.pMethod();                   //Person1
       person.pStaticMethod();             //Person2
  }
}

2、父类

package com.WZ.Demo.ClassSet;
public class Person {
   public void pMethod() {
       System.out.println("Person1");
  }
   public static void pStaticMethod() {
       System.out.println("Person2");
  }
}

3、子类

package com.WZ.Demo.ClassSet;
public class Student extends Person {
   public void sMethod() {
       System.out.println("Student1");
  }
   public static void sStaticMethod() {
       System.out.println("Student2");
  }
}

static关键字

静态代码块 static {}

只执行一次,随着类的产生而产生。

Person类:

package com.WZ.Demo.ClassSet;
public class Person {
   static {
       String name = "WangZan";
       int age = 25;
  }
}


final关键字

被final关键字修饰的类就断子绝孙了,不能被别人继承。

下面这个Person类,就不能被Student extends Person。否则报错。

package com.WZ.Demo.ClassSet;
public final class Person {
   static {
       String name = "WangZan";
       int age = 25;
  }
}

 

 

以上是关于Java的多态的主要内容,如果未能解决你的问题,请参考以下文章

每个人单核苷酸多态性(SNP)形成的原因是啥?

多态性和动态铸造

Java多态——代码复用性

Java 多态

java多态/重载方法——一个疑难代码引发的讨论

Java 多态