设计模式作业
package sdau;public class man {public static void main(String[] args) {show(new Cat()); // 以 Cat 对象调用 show 方法show(new Dog()); // 以 Dog 对象调用 show 方法Animal a = new Cat(); // 向上转型 a.eat(); // 调用的是 Cat 的 eatCat c = (Cat)a; // 向下转型 c.work(); // 调用的是 Cat 的 work} public static void show(Animal a) {a.eat(); // 类型判断if (a instanceof Cat) { // 猫做的事情 Cat c = (Cat)a; c.work(); } else if (a instanceof Dog) { // 狗做的事情 Dog c = (Dog)a; c.work(); } }
}abstract class Animal { abstract void eat();
} class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void work() { System.out.println("抓老鼠"); }
} class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } public void work() { System.out.println("看家"); }
}
1.
package sdau;
public class man {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
这个例子是为了说明多态存在的三个必要条件:
• 继承:要有继承关系,子类继承父类;
父类Animal中有eat()抽象方法,子类Dog,Cat继承eat(),并有自己的方法work(),
• 重写:子类要重写父类的方法;
重写eat()
• 父类引用指向子类对象。
这段 Java 代码主要演示了 Java 中的向上转型和向下转型操作。向上转型是将子类对象赋值给父类引用,而向下转型则是将父类引用强制转换回子类引用。
1. 向上转型
Animal a = new Cat(); // 向上转型
含义:创建了一个 Cat 类的对象,并将其赋值给一个 Animal 类型的引用变量 a。这就是向上转型,因为 Cat 是 Animal 的子类,子类对象可以自动转换为父类类型。
特点:通过父类引用 a 只能调用 Animal 类中定义的方法,但是实际执行的是 Cat 类中重写的方法
2. 调用方法
a.eat(); // 调用的是 Cat 的 eat
含义:调用 a 引用的 eat() 方法。由于 a 实际指向的是 Cat 类的对象,并且 Cat 类可能重写了 Animal 类的 eat() 方法,所以这里调用的是 Cat 类的 eat() 方法。
3. 向下转型
Cat c = (Cat)a; // 向下转型
含义:将 Animal 类型的引用 a 强制转换为 Cat 类型,并赋值给 Cat 类型的引用变量 c。这就是向下转型,需要使用强制类型转换运算符 (Cat)。
注意事项:向下转型是有风险的,因为只有当 a 实际指向的是 Cat 类的对象时,这种转换才是安全的。如果 a 指向的是其他 Animal 子类的对象,会抛出 ClassCastException 异常。
4. 调用子类特有的方法
c.work();
含义:调用 Cat 类特有的 work() 方法。通过向下转型,我们可以使用 Cat 类中定义的所有方法,包括 Animal 类中没有的方法。
2.
package sdau;
public class man {
public static void main(String [] args) {
Salary s = new Salary("员工 A", "北京", 3, 3600.00);
Employee e = new Salary("员工 B", "上海", 2, 2400.00);
System.out.println("使用 Salary 的引用调用 mailCheck -- ");
s.mailCheck();
System.out.println("\n使用 Employee 的引用调用 mailCheck--");
e.mailCheck();
}
}
class Employee {
private String name;
private String address;
private int number;
public Employee(String name, String address, int number) {
System.out.println("Employee 构造函数");
this.name = name;
this.address = address;
this.number = number;
}
public void mailCheck() {
System.out.println("邮寄支票给: " + this.name
+ " " + this.address);
}
public String toString() {
return name + " " + address + " " + number;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public void setAddress(String newAddress) {
address = newAddress;
}
public int getNumber() {
return number;
}
}
class Salary extends Employee
{
private double salary; // 全年工资
public Salary(String name, String address, int number, double salary) {
super(name, address, number);
setSalary(salary);
}
public void mailCheck() {
System.out.println("Salary 类的 mailCheck 方法 ");
System.out.println("邮寄支票给:" + getName()
+ " ,工资为:" + salary);
}
public double getSalary() {
return salary;
}
public void setSalary(double newSalary) {
if(newSalary >= 0.0) {
salary = newSalary;
}
}
public double computePay() {
System.out.println("计算工资,付给:" + getName());
return salary/52;
}
}
1. 体现了多态的基本概念:允许不同类的对象对同一消息做出不同的响应。
Employee e = new Salary("员工 B", "上海", 2, 2400.00);
e.mailCheck();
虽然变量 e 的类型是 Employee,但实际指向的是 Salary 类的对象。当调用 e.mailCheck() 时,执行的是 Salary 类中重写的 mailCheck() 方法,而不是 Employee 类中的 mailCheck() 方法,这就是多态的具体体现。
2. 方法重写的应用
方法重写是实现多态的重要手段。在这个例子中,Salary 类继承自 Employee 类,并重写了 mailCheck() 方法。
通过方法重写,Salary 类可以提供不同行为,从而实现了对同一方法的不同响应。
3. 提高代码的可扩展性和可维护性
多态可以使代码更加灵活和易于扩展。在这个例子中,如果将来需要添加一个新的员工类型,比如 Manager 类,只需要继承 Employee 类并重写 mailCheck() 方法即可,而不需要修改现有的 main() 方法。
4. 父类引用指向子类对象的优势
使用父类引用指向子类对象可以提高代码的通用性。在 main() 方法中,Employee 类型的变量可以引用 Salary 类的对象,这样可以将不同子类的对象统一处理,减少代码的冗余。
通过这种方式,可以方便地对不同类型的员工对象进行统一的操作,而不需要为每个子类单独编写处理代码。
综上所述,这个例子很好地展示了 Java 多态的基本概念、方法重写的应用以及多态在提高代码可扩展性和可维护性方面的优势,因此非常适合用于学习 Java 多态。
理解:父类引用指向子类对象的基本概念
在 Java 中,当一个类继承另一个类时,就会形成父子类关系。我们可以使用父类类型的变量来引用子类的对象,这就是 “父类引用指向子类对象”。例如代码中有:
Employee e = new Salary("员工 B", "上海", 2, 2400.00);
这里 Employee 是父类,Salary 是子类,e 是 Employee 类型的引用变量,但它指向的是一个 Salary 类的对象。
为什么要进行父类引用指向子类对象:
假设我们要对不同类型的员工对象进行某种操作,比如调用 mailCheck() 方法。如果不使用父类引用,我们可能需要为每个子类单独编写处理代码:
Salary s = new Salary("员工 A", "北京", 3, 3600.00);
s.mailCheck();
Manager m = new Manager("经理 A", "广州", 4);
m.mailCheck();
如果有很多子类,代码会变得非常冗长和重复。而使用父类引用,我们可以将不同子类的对象统一处理:
Employee[] employees = new Employee[2];
employees[0] = new Salary("员工 A", "北京", 3, 3600.00);
employees[1] = new Manager("经理 A", "广州", 4);
for (Employee emp : employees) {
emp.mailCheck();
}
这里定义了一个 Employee 类型的数组,数组中可以存放 Salary 类、Manager 类等 Employee 子类的对象。通过一个循环,我们可以对数组中的所有对象统一调用 mailCheck() 方法,而不需要关心每个对象具体是哪个子类的实例。
3.
package sdau;
public class man{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
}
}
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
}
这个例子是说明:多态的实现方式
4.