[英]What is the use of passing object to another class reference in java?
例如: Foo ab = new Dog();
将另一个类型类的对象保存到另一个类的引用!
不一定总是需要执行Foo foo = new Bar()
但是通常建议引用接口而不是实现。 这样,您可以更改实现而无需更改其他代码。 例如,如果您正在使用列表做某事,并且使用ArrayLists,则可以这样做:
ArrayList<Integer> numbers = new ArrayList<>();
//Do stuff with numbers
但是,您可能不在乎列表是哪种类型,因此最好选择
List<Integer> numbers = new ArrayList<>();
//Do stuff with numbers
现在,无论拥有哪种列表都没有关系,也许您会发现使用LinkedList可以获得更好的性能,并且可以使用它而不用更改任何其他代码。
我想说,当其他调用者接收对象时,多态性是最重要的。
是的,如果Foo是接口,则此方法可让您对代码进行更多控制。 您将实现Java编程语言的Polymorphism
,可Plug-ability
, Maintainability
和Loose coupling
特性。
假设您应该从应用程序连接到oracle并编写如下代码
OracleDrive driver= new OracleDriver()
driver.connect();
它会解决您的问题。 但这会使您的代码与OracleDriver紧密结合。 如果从类路径中删除与Oracle相关的jar,则您的应用程序将根本无法编译。 而且,如果有人要求您根据应用程序的配置使您的应用程序连接到不同的数据库,那么最终您将获得基于应用程序支持的数据库的多个if
。 按照编程标准,这是不好的做法。
如果所有数据库驱动器都实现了接口Driver
则可以根据配置加载驱动程序,而无需将代码紧密耦合到任何特定的驱动程序类,例如:
Driver driver = properties.get(db.driver.class)
driver.connect()
现在您看到需要更改应用程序以连接到MySql,您只需要在配置文件中设置该类即可。
希望你明白我的意思!
方法参数更有用。
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();
简单的答案,你不能那样做。
更复杂的答案,只有当“狗”的类型为“ Foo”时,您才可以这样做。 我们何时才能说Dog是'Foo'的类型,即Dog是实现Foo(如果是接口)还是扩展Foo(如果是其他类或抽象类)
现在,利用接口编码(问题的技术名称)的优势是
1)Java的多态性基于此(多态性使行为的运行时更改成为可能,有关更多信息,请google java中的多态性)2)您正在通过这种方法使接口独立于实现。
希望这回答了您的问题。
此类声明仅可能
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)
{
}
它可以接受所有从基类派生的对象,并根据基类的属性或功能执行操作。
在这里查看我的旧答案之一:
这是我的一位教授曾经告诉过我们的轶事。
长话短说,当您进入更复杂的系统时,您想要这样做的原因变得更加清楚。 能够将规范(接口/抽象类及其合同)与实现(混凝土类)分开的功能是一种强大的工具,可以非常轻松地编写新的实现,而不必在应用程序中的其他地方更改代码。 您可以在代码中使用规范,例如规范:
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) { ... }
然后,不执行Animal
,而Dog
, Cat
和Turtle
类将实现DomesticatedAnimal
。 例如:
public class Dog implements DomesticatedAnimal { ... }
这意味着Dog
既是因为它直接实现而实现的DomesticatedAnimal
, 又是因为DomesticatedAnimal
扩展了Animal
而继承的Animal
。 其他的动物Hyena
, Lion
和Panther
实现了Animal
接口。 这意味着我们的新方法不会像原始方法那样只使用任何Animal
,而是将其限制为特定种类的Animal
对象。 同时,使用原始Animal
接口编写的任何方法仍将对所有涉及的对象起作用。
您始终可以用对子类的引用代替基类。
换句话说,您始终可以使用更具体的内容代替更一般的内容-因此,如果您有一行代码询问“犬”,则可以向其发送对“狗”的引用。 所以这行代码:
Foo ab=new Dog();
意味着您要实例化一个新的Dog
对象,然后创建一个名为ab
的Foo
引用并将其指向该对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.