0
点赞
收藏
分享

微信扫一扫

Java类的设计----多态性及其应用


多态性及其应用


多态性

多态—在Java中,子类的对象可以替代父类的对象使用
一个变量只能有一种确定的数据类型
一个引用类型变量可能指向(引用)多种不同类型的对象
  Person p = new Student();
  Object o = new Person();//Object类型的变量o,指向Person类型的对象
  o = new Student(); //Object类型的变量o,指向Student类型的对象

父类类型的变量可以指向子类的对象

一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
  Student m = new Student();
  m.school = “pku”; //合法,Student类有school成员变量
  Person e = new Student();
  e.school = “pku”; //非法,Person类没有school成员变量

属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误。

虚拟方法调用(Virtual Method Invocation)

正常的方法调用
  Person e = new Person();
  e.getInfo();
  Student e = new Student();
  e.getInfo();
虚拟方法调用(多态情况下)
  Person e = new Student();
  e.getInfo(); //调用Student类的getInfo()方法
编译时类型和运行时类型

编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。—— 动态绑定

 

多态性应用举例

方法声明的形参类型为父类类型,可以使用子类的对象作为实参调用该方法

public class Test { 
  public void method(Person e) {
    //……
    e.getInfo();
  }
  public static void main(Stirng args[]) {
    Test t = new Test();
    Student m = new Student();
    t.method(m); //子类的对象m传送给父类类型的参数e
  }
}

 

Person类


1 public class Person {
2
3 //仅在类的内部可以访问.
4 private String email;
5 //在同一个包内该属性可以被访问.
6 String major;
7 //在子类中该属性可以被访问, 且该子类可以跨包
8 protected int salary;
9
10 //访问权限最高, 无论是否在一个包内, 无论是否是子类都可以被访问.
11 public String name;
12 public int age;
13 public Date birth;
14
15 private String lover;
16
17 public Person(int i) {
18 System.out.println("[Person's constructor...]");
19 }
20
21 public Person() {
22 // TODO Auto-generated constructor stub
23 }
24
25 public String getInfo(){
26 return "name: " + name + ", " + "age: " + age + ", " + "birth: " + birth;
29 }
30


Man类继承Person类


1 public class Man extends Person{
2
3 public void work(){
4 System.out.println("男人工作...");
5 }
6
7 @Override
8 public String getInfo() {
9 return "Man's getInfo";
10 }
11


Woman类继承Person类


1 public class Woman extends Person{
2
3 public void shopping(){
4 System.out.println("女人购物...");
5 }
6


TestPerson类


1 public class TestPerson {
2 public static void main(String[] args) {
3
4 //多态
5
6 //1. 创建一个 Man 的实例
7 Man m1 = new Man();
8
9 //2. 创建一个 Woman 的实例
10 Woman w1 = new Woman();
11
12 //3. 创建一个 Person 的实例
13 Person p1 = new Person();
14
15 /**
16 * 多态: 在Java中,父类的引用可以指向子类的对象.
17 * 1. 在多态情况下, 父类的实例变量不能再访问子类中添加的属性和方法
18 * 2. 方法的调用是在运行时确定的,所以调用的是 Man 类的 getInfo() 方法。—— 动态绑定(虚拟方法法调用)
19 * 3. 在存在父子关系(多态)的情况下, 可以把父类的引用类型强制转换为子类的引用类型. 若实际上不能进行转换则系统
20 * 会抛出 java.lang.ClassCastException 异常.
21 * 4. 如何避免出现 java.lang.ClassCastException 异常呢? 在转换之前可以先判断一下对象实际上是否为指定的子类类型.
22 * 使用 instanceof 运算符. 注意, 使用 instanceof 运算符, 必须要求前面的引用指向的变量和后边的类之间存在父子关系
23 */
24 //需要一个人, 但来的是一个男人! OK. 因为男人一定是一个人.
25 Person p2 = new Man();
26 System.out.println(p2.getInfo());
27
28 //需要一个人, 但来的是一个女人! OK. 因为女人一定是一个人
29 Person p3 = new Woman();
30
31 //在多态情况下, 可以进行强制的类型转换
32 Man m2 = (Man) p2;
33
34 System.out.println(p3 instanceof Man);
35 System.out.println(p3 instanceof Woman);
36
37 // System.out.println(m2 instanceof Person);
38
39 // Man m3 = (Man) p3;
40
41 //需要一个男人, 但来的是个人! NO. 因为人不一定是男人.
42 //Man m2 = new Person();
43
44 //需要个男人, 但来的是一个女人。 NO!
45 //Man m3 = new Woamn();
46
47 Student student = new Student();
48 student.name = "Jerry";
49 student.birth = new Date();
50 student.age = 1;
51 student.school = "atguigu";
52
53 System.out.println(student.getInfo());
54 }
55


 

instanceof 操作符

x instanceof A:检验x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
如果x属于类A的子类B,x instanceof A值也为true。
public class Person extends Object {…}
public class Student extends Person {…}
public class Graduate extends Person {…}

public void method1(Person e) {
  if (e instanceof Person)
    // 处理Person类及其子类对象
  if (e instanceof Student)
    //处理Student类及其子类对象
  if (e instanceof Graduate)
    //处理Graduate类及其子类对象
}

 

练习

建立TestInstance 类,在类中定义方法method1(Person e); 在method1中:

(1)根据e的类型调用相应类的getInfo()方法。

(2)根据e的类型执行: 如果e为Person类的对象,输出:“a person”; 如果e为Student类的对象,输出 “a student” “a person ” 如果e为Graduate类的对象,输出: “a graduated student” “a student” “a person”


1 class Person {
2 protected String name="person";
3 protected int age=50;
4 public String getInfo() {
5 return "Name: "+ name + "\n" +"age: "+ age;
6 }
7 }
8 class Student extends Person {
9 protected String school="pku";
10 public String getInfo() {
11 return "Name: "+ name + "\nage: "+ age + "\nschool: "+ school;
13 }
15 }
16 class Graduate extends Student {
17 public String major="IT";
18 public String getInfo(){
20 return "Name: "+ name + "\nage: "+ age + "\nschool: "+ school+"\nmajor:"+major;
22 }
23


 

 

对象类型转换 (Casting )

基本数据类型的Casting:
  小的数据类型可以自动转换成大的数据类型
    如long g=20; double d=12.0f
  可以把大的数据类型强制转换(casting)成小的数据类型
    如 floate f=(float)12.0 int a=(int)1200L

对Java对象的强制类型转换称为造型
  从子类到父类的类型转换可以自动进行
  从父类到子类的类型转换必须通过造型(强制类型转换)实现
  无继承关系的引用类型间的转换是非法的
  在造型前可以使用instanceof操作符测试一个对象的类型

对象类型转换举例
public class Test {
//设Person类中没有getschool()方法
//非法,编译时错误

    if(e instanceof Student) {
//将e强制转换为Student类型
      System.out.pritnln(me.getschool());
    }
  }

  public static void main(Stirng args[]) {
    Test t = new Test();
    Student m = new Student();
    t.method(m);
  }
}

 

Person类

 


1 public class Person {
2 protected String name="person";
3 protected int age=50;
4 public String getInfo() {
5 return "Name: "+ name + "\n" +"age: "+ age;
6 }
7 }
8 class Student extends Person {
9 protected String school="pku";
10 public String getInfo() {
11 return "Name: "+ name + "\nage: "+ age
12 + "\nschool: "+ school;
13 }
14
15 }
16 class Graduate extends Student{
17 public String major="IT";
18 public String getInfo()
19 {
20 return "Name: "+ name + "\nage: "+ age
21 + "\nschool: "+ school+"\nmajor:"+major;
22 }
23


 

TestInstance类


1 package com.atgugu.java.ex;
2
3 public class TestInstance {
4
5 /*
6 在类中定义方法method1(Person e);
7 在method1中:
8 (1)根据e的类型调用相应类的getInfo()方法。
9 (2)根据e的类型执行:
10 如果e为Person类的对象,输出:“a person”;
11 如果e为Student类的对象,输出
12    “a student”
13    “a person ”
14 如果e为Graduate类的对象,输出:
15    “a graduated student”
16    “a student”
17    “a person”
18 */
19
20 public void method1(Person e) {
21 String info = e.getInfo();
22 System.out.println(info);
23
24 if(e instanceof Graduate){
25 System.out.println("a graduated student");
26 }
27 if(e instanceof Student){
28 System.out.println("a student");
29 }
30 if(e instanceof Person){
31 System.out.print("a person");
32 }
33
34 System.out.println("\n");
35
36 }
37
38 public static void main(String[] args) {
39
40 TestInstance ti = new TestInstance();
41
42 Person p1 = new Person();
43 ti.method1(p1);
44
45 Person p2 = new Student();
46 ti.method1(p2);
47
48 Person p3 = new Graduate();
49 ti.method1(p3);
50 }
51


 

举报

相关推荐

0 条评论