多态
多态的基本使用
实体类
package Person;
public class Person { String name; int age; public void eat(){ System.out.println("人吃饭"); }
public void walk(){ System.out.println("人走路"); }
}
package Person;
public class Man extends Person{ boolean isSomking;
public void eat(){ System.out.println("男人吃肉"); }
public void walk(){ System.out.println("男人走路"); }
public void play(){ System.out.println("男人打游戏"); } }
package Person;
public class Woman extends Person{ boolean isBeauty; public void eat(){ System.out.println("女人吃甜点"); }
public void walk(){ System.out.println("女人走路"); }
public void watch(){ System.out.println("女人看剧"); } }
|
package Person;
public class PersonTest { public static void main(String[] args) { Person person = new Person(); person.eat(); person.walk();
Man man = new Man(); man.eat(); man.walk();
Woman woman = new Woman(); woman.eat(); woman.walk();
System.out.println("*********多态性********");
Person person1 = new Man(); person1.eat(); person1.walk();
Person person2 = new Woman(); person2.eat(); person2.walk(); } }
|
测试方法
package Person;
public class PersonTest { public static void main(String[] args) { Person person = new Person(); person.eat(); person.walk();
Man man = new Man(); man.eat(); man.walk();
Woman woman = new Woman(); woman.eat(); woman.walk();
System.out.println("*********多态性********");
Person person1 = new Man(); person1.eat(); person1.walk();
Person person2 = new Woman(); person2.eat(); person2.walk();
}
}
|
输出结果
多态的实际使用
测试方法
package Person;
public class AccountTest { public static void main(String[] args) { AccountTest test = new AccountTest(); test.console(new Account()); System.out.println("-------------"); test.console(new CheckAccount()); System.out.println("-------------"); test.console(new SaveAccount()); } public void console(Account account){ account.saveMoney(100); account.getMoney(40); }
public void console(CheckAccount account){ account.saveMoney(100); account.getMoney(40); }
public void console(SaveAccount account){ account.saveMoney(100); account.getMoney(40); }
} class Account { String username; String password; int money;
public void saveMoney(int money) { this.money = money; System.out.printf("普通账户余额为: %d\n", this.money); }
public void getMoney(int money) { if(money <= this.money) { this.money -= money; System.out.printf("普通账户余额为: %d\n", this.money); } else { System.out.println("普通账户余额不足"); } } }
class CheckAccount extends Account { int quota = 500; public void saveMoney(int money) { this.money = money + quota; System.out.printf("信用卡账户余额为: %d\n", this.money); }
public void getMoney(int money) { if(this.money >= money) { this.money -= money; System.out.printf("信用卡余额为: %d\n", this.money); } else { System.out.println("信用卡余额不足"); } }
}
class SaveAccount extends Account { float money; float rate = 0.2F; float interest;
public void saveMoney(int money) { interest = money * rate; this.money = money + interest; System.out.printf("储蓄卡预期余额为: %f\n", this.money); }
public void getMoney(int money) { if(this.money - interest > money) { this.money -= money; System.out.printf("储蓄卡余额为: %f\n", this.money); } else { System.out.println("储蓄卡余额不足"); } } }
|
正常情况下,如果没有 Java 的多态性,那么对于不同对象的方法调用,就需要如下这样写多个同名方法,赋予不同对象的形参
public void console(Account account){ account.saveMoney(100); account.getMoney(40); }
public void console(CheckAccount account){ account.saveMoney(100); account.getMoney(40); }
public void console(SaveAccount account){ account.saveMoney(100); account.getMoney(40); }
|
而因为 Java 的多态性,这里的方法便可以省略重复调用,在实际的项目中,多态很有用,符合开闭原则。对于增加新的子类,方法都不需要进行改变,只定义一个父类即可。
public void console(Account account){ account.saveMoney(100); account.getMoney(40); }
|
输出结果
Java 向下转型
测试方法
虽然创建的子类的对象,也加载了子类的特有的方法和属性,但是因为我们声明的是父类的引用,所以没有办法直接调用子类特有的属性和方法。
注意,在向下转型的时候可能会出现类型转换异常,即你要转换的类型并不是你声明的类型
所以在进行向下转型之前,为了程序的健壮性,最好使用 instanceof 进行判断
public class AccountTest { public static void main(String[] args) { AccountTest test = new AccountTest(); test.console(new CheckAccount()); test.console(new SaveAccount()); } public void console(Account account){ account.saveMoney(100); account.getMoney(40); if (account instanceof CheckAccount){ CheckAccount check_account = (CheckAccount)account; check_account.getQuota(); }
if (account instanceof SaveAccount){ SaveAccount save_account = (SaveAccount)account; save_account.getInterest(); save_account.getRate(); }
}
}
|
输出结果
多态案例练习
题目
关系图
实体类
package Geometric;
public class GeometricObject { protected String color; protected double weight;
protected GeometricObject(String color, double weight) { this.color = color; this.weight = weight; }
public String getColor() { return color; }
public void setColor(String color) { this.color = color; }
public double getWeight() { return weight; }
public void setWeight(double weight) { this.weight = weight; }
public double findArea(){ return 0; } }
package Geometric;
public class Circle extends GeometricObject { private double radius;
public Circle(String color, double weight, double radius) { super(color, weight); this.radius = radius; }
public double getRadius() { return radius; }
public void setRadius(double radius) { this.radius = radius; }
@Override public double findArea(){ return 3.14 * radius * radius; } }
package Geometric;
public class MyRectangle extends GeometricObject{ private double width; private double height;
public MyRectangle(String color, double weight, double width, double height) { super(color, weight); this.width = width; this.height = height; }
public double getWidth() { return width; }
public void setWidth(double width) { this.width = width; }
public double getHeight() { return height; }
public void setHeight(double height) { this.height = height; }
@Override public double findArea() { return width * height; } }
|
测试方法
package Geometric;
import Person.Man;
public class GeometricTest {
public static void main(String[] args) { GeometricTest test = new GeometricTest(); Circle c1 = new Circle("red", 1.0, 4); Circle c2 = new Circle("bule", 1.0, 4); MyRectangle m1 = new MyRectangle("red", 1.0, 4, 4); test.displayGeometricObject(c1); test.displayGeometricObject(c2); test.displayGeometricObject(m1);
boolean isEquals = test.equalsArea(c1, c2); if (isEquals){ System.out.println("面积相等"); } else { System.out.println("面积不等"); }
} public boolean equalsArea(GeometricObject object1, GeometricObject object2){ return object1.findArea() == object2.findArea(); }
public void displayGeometricObject(GeometricObject object){ System.out.println("几何图形的面积为: " + object.findArea()); } }
|
输出结果
重写对象方法
重写 Object 类的 equals() 方法
对于 String,File ,包装类等已经重写了 Object 的 equals 方法。我们自己用的时候,通常也可以重写 equals 方法实现对象的应用。
当然 IDEA 自带重写 equals 方法
实体类
class User { private int age; private String name;
public User() { }
public User(int age, String name) { this.age = age; this.name = name; }
@Override public boolean equals(Object obj) { if (this == obj) { return true; }
if (obj instanceof User) { User user = (User) obj; return this.age == user.age && this.name.equals(user.name); }
return false; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (age != user.age) return false; return Objects.equals(name, user.name); } }
|
测试方法
public class UserTest { public static void main(String[] args) {
User u1 = new User(10, "lihua"); User u2 = new User(10, "xiaoli"); User u3 = new User(10,"lihua"); System.out.println(u1.equals(u2)); System.out.println(u1.equals(u3)); } }
|
输出结果
重写 toString() 方法
和 equals 一样,String,File 等也已经预先重写了 toString 方法,对于自定义类,我们同样可以进行重写
@Override public String toString() { return "Use r" + "name: " + name + " age: " + age; }
|
当然,IDEA 也可以自动生成对象的 toString 方法
@Override public String toString() { return "User{" + "age=" + age + ", name='" + name + '\'' + '}'; }
|
关键字 Static