What is the use of passing object to another class reference in java?
例如:foo();AB =新的狗
节能型到另一个类的对象引用另一个类的大学!
是的,如果foo是一个接口,那么这种方法可以让您对代码有更多的控制。实现了EDCOX1、2、EDCOX1、3、EDCOX1、4和EDCOX1、5、Java编程语言的特点。
假设您要从应用程序连接到Oracle并编写这样的代码
1 2 | OracleDrive driver= new OracleDriver() driver.connect(); |
它会解决你的问题。但会使您的代码与OracleDriver紧密耦合。如果从类路径中删除与Oracle相关的JAR,则应用程序根本不会编译。如果有人要求您根据配置将应用程序连接到不同的DBS,那么您最终会得到基于您的应用程序支持的DBS的多个
如果您所有的DB驱动器都实现了一个接口
1 2 |
现在您看到需要更改应用程序以连接到MySQL,只需要在配置文件中设置该类。
希望你明白我的意思!
并不总是需要做像
1 2 | ArrayList<Integer> numbers = new ArrayList<>(); //Do stuff with numbers |
不过,你可能不在乎它是什么样的列表,所以你可能会更好地
1 2 | List<Integer> numbers = new ArrayList<>(); //Do stuff with numbers |
现在,不管你有什么样的列表,也许你会发现LinkedList的性能会更好,你可以使用它而不是更改任何其他代码。
不过,当其他调用方接收对象时,多态性是最重要的。
它对方法参数更有用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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); } } |
在这种情况下,一个人可以剃任何动物的毛,但我们把它当作狗。
因为我们知道菲多是一只狗,所以
1 2 3 4 5 | Animal pet; if(joe.prefersCats) pet = new Cat(); else pet = new Dog(); |
您总是可以用对子类的引用代替基类。
换句话说,你可以用一些更具体的东西来代替更一般的东西,所以如果你有一行代码要求一只狗,你可以把它作为参考发送给一只狗。所以这行代码:
1 | Foo ab=new Dog(); |
意味着您正在实例化一个新的
请看我的一个老答案:
使用接口有什么好处
这是我的一位教授曾经告诉我们的一件轶事。
长话短说,当你进入更复杂的系统时,你想要这样做的原因就变得更清楚了。将规范(接口/抽象类及其契约)与实现(具体类)分离的能力是一个强大的工具,它使编写新的实现变得非常容易,而不必在应用程序的其他地方更改代码。您在代码中使用规范,例如规范:
1 | public interface Animal { ... } |
您的实施:
1 | public class Dog implements Animal { ... } |
然后在代码中,尽可能使用规范:
1 2 | Animal a = new Dog(); a.eat(); // All animals eat, so eat() is on the Animal interface |
除非您绝对需要使用实现本身:
1 2 | Dog d = new Dog(); d.bark(); // Other animals don't bark, so we need to have the Dog here |
这会使代码更清晰。例如,假设我有一个方法
1 2 3 4 5 | public static void feedAndGroom(Cat c) { ... } public static void feedAndGroom(Dog d) { ... } public static void feedAndGroom(Turtle t) { ... } |
根据具体情况,每个代码块甚至可能看起来完全相同。更糟糕的是,当有人发现一只新动物时会发生什么?我们每次都必须添加一个新方法,这将导致大量的方法。所有这些重复的解决方案是围绕功能创建一个接口,然后使用一种方法:
1 | public static void feedAndGroom(Animal a) { ... } |
这需要实现
1 2 3 | feedAndGroom(new Cat()); feedAndGroom(new Dog()); feedAndGroom(new Turtle()); |
但是,这些方法调用也是合法的:
1 2 3 | feedAndGroom(new Hyena()); feedAndGroom(new Lion()); feedAndGroom(new Panther()); |
我们可能不想尝试喂养和培育这些动物,至少不想饲养野生动物,因此我们可以添加一个名为
1 | public interface `DomesticatedAnimal` extends `Animal` { ... } |
将我们的方法改为:
1 | public static void feedAndGroom(DomesticatedAnimal da) { ... } |
然后,
1 | public class Dog implements DomesticatedAnimal { ... } |
这意味着,由于
这种类型的声明只可能
1 | Foo ab=new Dog(); |
如果dog类扩展了类foo,或者foo是一个接口,由dog类实现为
1 | class Dog extends Foo { .... } |
或
1 | class Dog implements Foo { ... } //Here Foo is an interface |
我认为如果用继承的接口或继承的类初始化类对象作为所有的基类函数,那么属性将在派生类对象中可用。如果用不同的派生类初始化具有相同基类的多个对象,这种类型的声明将非常有用。例如,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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 { } |
如果正在初始化
1 | MyObject file = new MyFile(); |
这确实没有用,但当我们想要初始化
1 2 3 | List<MyObject> listOfFilesFolders = new ArrayList<MyObject>(); listOfFilesFolders.add(new MyFile()); listOfFilesFolders.add(new MyFolder()); |
此"listofilesfolders"可以是另一个类的私有变量,该类保持存在文件/文件夹列表。
或者我们想有一个功能
1 2 3 4 | private void SomeFunction(MyObject obj) { } |
它可以获取从基类派生的所有对象,并根据基类属性或函数执行操作。
简单的答案,你不能这样做。
更复杂的答案是,只有当"狗"是"foo"的类型时,你才能做到这一点。什么时候我们会说dog是"foo"的类型,如果dog实现foo(如果是接口)或扩展foo(如果是其他类或抽象类)
现在,到接口编码(问题的技术名称)的好处是
1)Java的多态性是基于此的(多态性使得行为的运行时改变成为可能,请在Java中使用谷歌多态性获得更多信息)2)您通过这种方法使接口独立于实现。
希望这能回答你的问题。