实验九 多态、接口

一、实验预热
1、请叙述接口与抽象类的相同点和不同点。
1)关键字
interface
abstract

2)组成
抽象方法、全局常量
构造方法、普通方法、抽象方法、static方法、常量、变量

3)子类使用
implements 接口
extends 抽象类

4)关系
不能继承抽象类
可以实现多个接口

5)权限
只能使用public权限
可以使用各种权限

6)限制
没有单继承局限
单继承局限

7)子类
子类必须要覆写全部的抽象方法

8)实例化对象
依靠子类向上转型

2、请举出并描述生活中一些可以用接口定义标准的例子。
人和猪都会吃饭,但人要工作,猪不需要工作,可以定义一个吃饭的接口。

二、实验内容
1、工厂模式
如果想要确认一个代码是否真的好,有这么几个标准:
1)客户端调用简单,不需要关注具体的细节
2)客户端之外的代码修改,不影响用户的使用,即用户可以不用去关心代码是否变更
请阅读以下代码:

interface Fruit {
    public void eat();
}

class Apple implements Fruit {
    public void eat() {
        System.out.println("吃苹果");
    }
}

class Orange implements Fruit {
    public void eat() {
        System.out.println("吃橘子");
    }
}

public class Test {
    public static void main(String[] args) {
        Fruit f = new Apple();
        // Fruit f = new Orange();
        f.eat();
    }
}

请在以上代码的基础上进行修改,增添Factory类,此类只包含一个静态方法,用来通过判断输入的字符串来实例化不同水果类型的实例。
代码:

package leif.tests;

public class ExperimentalReport {
    public static void main(String[] args) {
        Factory.getInstance("").eat();
        Factory.getInstance("Apple").eat();
        Factory.getInstance("Orange").eat();
    }
}

interface Fruit {
    public void eat();
}

class Apple implements Fruit {
    @Override
    public void eat() {
        System.out.println("吃苹果");
    }
}

class Orange implements Fruit {
    @Override
    public void eat() {
        System.out.println("吃橘子");
    }
}

class Factory {
    private Factory() {
    };

    public static Fruit getInstance(String fruit) {
        switch (fruit) {
        case "Apple":
            return new Apple();
        case "Orange":
            return new Orange();
        }

        return new Fruit() {
            @Override
            public void eat() {
                System.out.println("吃水果");
            }
        };
    }
}

结果截图:


实验九 多态、接口_第1张图片
image.png

2、代理模式
1)简单描述什么是代理模式
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

2)代理模式的好处是什么
那先要说一下代理模式中的三种角色了。
抽象角色:声明真实对象和代理对象的共同接口。
代理角色:代理对象内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象,同时代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理对象所代表的真实对象,是最终要引用的对象。
代理模式的一个好处就是对外部提供统一的接口方法,而代理类在接口中实现对真实类的附加操作行为,从而可以在不影响外部调用情况下,进行系统扩展。
例如:接口A有一个接口方法operator(),RealA实现接口A,则必须实现接口方法operator(),现在新需求需要修改RealA中的operator(),如果修改RealA就会影响原有系统的稳定性,还要重新测试,这时就需要代理类实现附加行为操作。创建代理ProxyA实现接口A,并将真实对象RealA注入进来,ProxyA实现接口方法operator(),另外还可以增加附加行为,然后调用真实对象的operator(),从而保证了系统的稳定性。

3)何种情况下使用代理模式
当我们需要使用的对象很复杂或者需要很长时间去构造,这时就可以使用代理模式(Proxy)。例如如果构建一个对象很耗费时间和计算机资源,代理模式(Proxy)允许我们控制这种情况,直到我们需要使用实际的对象。一个代理(Proxy)通常包含和将要使用的对象同样的方法,一旦开始使用这个对象,这些方法将通过代理(Proxy)传递给实际的对象。

4)一个代理模式的简单例子:
A1想吃饭,于是让B带饭,正好A2也想吃饭,所以B也要顺便给A2带饭,写出代码和输出。
代码:

package leif.tests;

public class ExperimentalReport {
    public static void main(String[] args) {
        BringFood bringFood = new B();
        ((B)bringFood).setBringFood(new A1());
        bringFood.findSomeone();
        ((B)bringFood).setBringFood(new A2());
        bringFood.findSomeone();
    }
}

interface BringFood {
    public abstract void findSomeone();
}

class A1 implements BringFood {
    @Override
    public void findSomeone() {
        System.out.println("A1找人带饭");
    }
}

class A2 implements BringFood {
    @Override
    public void findSomeone() {
        System.out.println("A2找人带饭");
    }
}

class B implements BringFood {
    private BringFood bringFood;

    public BringFood getBringFood() {
        return bringFood;
    }

    public void setBringFood(BringFood bringFood) {
        this.bringFood = bringFood;
    }

    @Override
    public void findSomeone() {
        bringFood.findSomeone();
    }
}

结果截图:


实验九 多态、接口_第2张图片
image.png

你可能感兴趣的:(实验九 多态、接口)