对于接口而言,必须有子类,并且子类可以通过对象的向上转型来获取接口的实例化对象;
但是在进行对象实例化的过程中也可能存在有设计问题。
1:问题的产生
interface IFood { // 定义一个食物标准
public void eat() ; // 吃
}
class Bread implements IFood { // 定义一种食物
public void eat() {
System.out.println("吃面包。") ;
}
}
public class JavaDemo {
public static void main(String args[]) {
IFood food = new Bread() ;
food.eat() ;// 吃面包
}
}
//在本程序之中根据接口进行子类的定义,并且利用对象的向上转型进行接口对象实例化处理
程序的结构如下:
客户端需要明确知道具体的哪一个子类,如果现在面包吃腻,需要牛奶了,那么客户端需要做出修改。(就是new后边的类改变了)
interface IFood { // 定义一个食物标准
public void eat() ; // 吃
}
class Bread implements IFood { // 定义一种食物
public void eat() {
System.out.println("吃面包。") ;
}
}
class Milk implements IFood { // 定义一种食物
public void eat() {
System.out.println("喝牛奶。") ;
}
}
public class Test {
public static void main(String args[]) {
IFood food = new Milk() ;
food.eat() ;// 喝牛奶。
}
}
IFood food = new Milk() ;//需要不停修改类的名称
此时的程序就表示出现有耦合问题,由于“关键字new”。以JVM的设计为例,java实现可移植性的关键在于:JVM,而JVM的核心原理:利用一个虚拟机来进行Java程序,所有的程序并不与具体的操作系统有关,而由JVM来进行匹配,所以良好的设计应该避免耦合。
//利用工厂模式解决耦合问题;
interface IFood { // 定义一个食物标准
public void eat() ; // 吃
}
class Bread implements IFood { // 定义一种食物
public void eat() {
System.out.println("吃面包。") ;
}
}
class Milk implements IFood { // 定义一种食物
public void eat() {
System.out.println("喝牛奶。") ;
}
}
class Factory {
public static IFood getInstance(String className) {
if ("bread".equals(className)) {
return new Bread() ;
} else if ("milk".equals(className)) {
return new Milk() ;
} else {
return null ;
}
}
}
public class JavaDemo {
public static void main(String args[]) {
IFood food = Factory.getInstance(args[0]) ;
food.eat() ;// 吃面包
}
}
在上述程序中,客户端程序类与IFood接口的子类没有任何的关联,所有的关联都是通过Factory类完成的。
总结:如果日后进行子类扩充的时候只需要修改Factory程序类即可实现。