在java中将对象传递给另一个类引用有什么用?

时间:2013-10-07 04:49:54

标签: java

例如: Foo ab = new Dog();

将另一个类型类的对象保存到另一个类的引用中!

7 个答案:

答案 0 :(得分:2)

并不总是需要做Foo foo = new Bar()这样的事情,但通常建议您参考界面而不是实现。 这样您就可以更改实现而无需更改其他代码。 例如,如果您正在使用列表执行某些操作并使用ArrayLists,则可以执行以下操作:

ArrayList<Integer> numbers = new ArrayList<>();
//Do stuff with numbers

但是你可能不在乎它是什么类型的列表所以你可能最好用

List<Integer> numbers = new ArrayList<>();
//Do stuff with numbers

现在你有什么样的List并不重要,也许你发现使用LinkedList可以获得更好的性能,你可以使用它而不是更改任何其他代码。

我会说多态性在接收其他呼叫者的对象时最为重要。

答案 1 :(得分:2)

是的,如果Foo是一个接口,那么这种方法可以让您更好地控制代码。您实现了java编程语言的PolymorphismPlug-abilityMaintainabilityLoose coupling特征。

假设您应该从应用程序连接到oracle并编写像这样的代码

    OracleDrive driver= new OracleDriver()
    driver.connect();

它将解决您的问题。但是会使你的代码与OracleDriver紧密结合。如果从类路径中删除Oracle相关jar,则根本不会编译应用程序。如果有人要求您根据他们的配置让您的应用程序连接到不同的数据库,那么您最终会根据应用程序支持的数据库获得多个if。根据编程标准,这是不好的做法。

如果所有数据库驱动器都实现了接口Driver,那么您可以根据配置加载驱动程序,而无需将代码紧密耦合到任何特定的驱动程序类,如此

Driver driver = properties.get(db.driver.class)
driver.connect()

现在您看到需要更改应用程序以连接到MySql,您只需在配置文件中设置该类。

希望你明白我的意思!

答案 2 :(得分:1)

使用方法参数更有用。

class Animal {
    public boolean hasHair = true;
    public void speak() {}
}

class Dog extends Animal {
    public void speak() {
        System.out.println("Woof!");
    }
}

class Person {
    public void shave(Animal a) {
        a.hasHair = false;
        a.speak();
    }
}

class Main {
    public static void main(String[] args) {
        Person joe = new Person();
        Dog fido = new Dog();
        joe.shave(fido);
    }
}

在这种情况下,一个人可以剃掉任何动物,但我们将它传给狗。

Animal fido = new Dog();不太有用,因为我们知道fido是一只狗,但请考虑一下:

Animal pet;
if(joe.prefersCats)
    pet = new Cat();
else
    pet = new Dog();

答案 3 :(得分:0)

简单回答,你做不到。

更复杂的答案,只有'狗'是'Foo'的类型,你才能做到这一点。 我们什么时候会说Dog是'Foo'的类型,如果Dog实现Foo(如果是接口)或扩展Foo(如果是另一个类或抽象类)

现在,使用Coding to Interfaces(问题的技术名称)的优势是

1)Java的多态性基于此(多态性使行为可以改变行为,请在java中使用google polymorphism获取更多信息) 2)您通过这种方法使接口独立于实现。

希望这能回答你的问题。

答案 4 :(得分:0)

这种声明只能是

 Foo ab=new Dog();

如果Dog类扩展了类Foo或Foo是一个由Dog类实现的接口

class Dog extends Foo { .... }

class Dog implements Foo { ... } //Here Foo is an interface

我认为如果使用继承接口或继承类初始化类对象作为所有基类函数是没有用的,属性将在派生类对象中可用。如果要初始化具有相同基类且具有不同派生类的多个对象,则此类型的声明将派上用场 例如,

public class MyObject
{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class MyFile extends MyObject
{
    private String extension;

    public String getExtension() {
        return extension;
    }

    public void setExtension(String extension) {
        this.extension = extension;
    }
}

public class MyFolder extends MyObject
{

}

如果您正在初始化

MyObject file = new MyFile();

这真的没用,但是当我们想要初始化

时它会很有用
List<MyObject> listOfFilesFolders = new ArrayList<MyObject>();
listOfFilesFolders.add(new MyFile());
listOfFilesFolders.add(new MyFolder());

这个'listOfFilesFolders'可以是另一个类的私有变量,它保存文件/文件夹列表。

或者我们希望功能为

private void SomeFunction(MyObject obj)
{

}

可以获取从基类派生的所有对象,并根据基类属性或函数执行操作。

答案 5 :(得分:0)

请在此处查看我的旧答案之一:

What is the advantage of using interfaces

这是一篇关于我的一位教授曾告诉过我们的轶事的轶事。

长话短说,当你进入更复杂的系统时,你想要这个的原因变得更加清晰。将规范(接口/抽象类及其契约)与实现(具体类)分开的能力是一个强大的工具,使得编写新实现非常容易,而无需在应用程序的其他地方更改代码。您可以在代码中使用该规范,例如规范:

public interface Animal { ... }

您的实施:

public class Dog implements Animal { ... }

然后在代码中,尽可能使用规范:

Animal a = new Dog();
a.eat(); // All animals eat, so eat() is on the Animal interface

除非您绝对需要使用实现本身:

Dog d = new Dog();
d.bark(); // Other animals don't bark, so we need to have the Dog here

这使您的代码更清晰。例如,假设我有方法feedAndGroom。如果我没有界面,我需要为每个我想支持的动物创建一个新方法:

public static void feedAndGroom(Cat c) { ... }

public static void feedAndGroom(Dog d) { ... }

public static void feedAndGroom(Turtle t) { ... }

根据具体情况,每个代码块甚至可能看起来完全相同。更糟糕的是,当有人发现新动物时会发生什么?我们每次都必须添加一个新方法,这将导致大量的方法。所有这些重复的解决方案是围绕功能创建一个接口,然后有一个方法:

public static void feedAndGroom(Animal a) { ... }

这将采用任何实现Animal接口的方法。所有这些方法调用都是合法的:

feedAndGroom(new Cat());
feedAndGroom(new Dog());
feedAndGroom(new Turtle());

但是,这些方法调用也是合法的:

feedAndGroom(new Hyena());
feedAndGroom(new Lion());
feedAndGroom(new Panther());

我们可能不想尝试喂养和培养这些动物,至少不是野生动物,所以我们可以添加一个名为DomesticatedAnimal的新界面,扩展Animal

public interface `DomesticatedAnimal` extends `Animal` { ... }

将我们的方法改为:

public static void feedAndGroom(DomesticatedAnimal da) { ... }

然后AnimalDogCat类将实施Turtle,而不是实施DomesticatedAnimal。例如:

public class Dog implements DomesticatedAnimal { ... }

这意味着Dog都是DomesticatedAnimal,因为它直接实现了它,继承Animal,因为DomesticatedAnimal扩展Animal 1}}。其他动物HyenaLionPanther只是实现Animal界面。这意味着我们的新方法不会像我们的原始方法那样只使用任何Animal,而是将其限制为特定类型的Animal对象。同时,任何使用原始Animal接口编写的方法仍然适用于所有相关对象。

答案 6 :(得分:0)

您始终可以将引用替换为子类来代替基类。

换句话说,你总是可以使用更具体的东西代替更一般的东西 - 所以如果你有一行代码请求犬,你可以向它发送一个狗的参考。 所以这行代码:

Foo ab=new Dog();

表示您正在实例化一个新的Dog对象,然后创建一个 Foo引用名为ab并将其指向该对象。

相关问题