抱歉,标题令人困惑,我有点困惑,所以我只使用一个示例:D假设我们有:
public abstract class Vehicle {
public abstract void paint();
}
public class Car extends Vehicle {
public void paint() {
...
}
public void sell() {
...
}
}
Car c = new Car();
c.paint();
c.sell(); //works
Vehicle c = new Car();
c.paint();
c.sell(); //error
那么使用后一种格式有什么意义呢?我只能想到限制/隐私,但即使那样也不能想到一个合理的例子。哪个选项更适合作为一般做法?
答案 0 :(得分:1)
我不是专家,但据我所知
以后的格式用于实现抽象,即隐藏函数的内部工作。
现在,实现取决于扩展您的function listAllUsers(nextPageToken) {
// List batch of users, 1000 at a time.
admin.auth().listUsers(1000, nextPageToken)
.then(function(listUsersResult) {
listUsersResult.users.forEach(function(userRecord) {
console.log('user', userRecord.toJSON());
});
if (listUsersResult.pageToken) {
// List next batch of users.
listAllUsers(listUsersResult.pageToken);
}
})
.catch(function(error) {
console.log('Error listing users:', error);
});
});
// Start listing users from the beginning, 1000 at a time.
listAllUsers();
类的类(此处为Vehicle
)。
这样您就可以自由地实现绘画功能,而不必担心哪个类正在实现它。
例如:
Car
现在您实现
Bike extends Vehicle {
// body
}
,根据您的配置,您可以喷涂自行车或汽车。如果使用得当,它会非常强大
使用Vehicle.paint()
也很不错,因为它强制Java使用空方法。
如果您想知道为什么会出错,那是因为interface
不知道函数Vechicle
存在,因为该函数是由类sell
而不是Car
定义的,但是Vechicle
的运行就像运行paint()
一样。
答案 1 :(得分:0)
原因是类型安全之一。如果Car
可以扩展Vehicle
,则大概其他类也可以。由于sell()
不是Vehicle
的接口的一部分,因此不需要子类来实现它。因此,例如,如果您拥有Bicycle extends Vehicle
,但由于某种原因而没有方法sell()
,那么您将必须获得运行时错误:
vehicle.sell()
和vehicle
指的是Bicycle
的实例。因此,如果方法sell()
应该在Vehicle
的所有子类型上都是可调用的,则is也应该是其接口的一部分。
答案 2 :(得分:0)
超级类意味着您在某些类之间有一些共同点,这些共同点可能是属性或method.abstract
类意味着您有一些概念,可能需要通过其子类来实现其某些方法。
您可能会在应用程序中的某个地方需要vehicle
概念,无论它是什么车辆,都需要对其进行涂漆,因此,您只需要知道传递的参数是车辆即可。
两个概念都是正确的,但这取决于您的用法和设计。
如果您只需要车辆概念而不管其子类型如何,则必须使用第二个概念,在这种情况下,您需要使用方法sell()
,因为您使该方法可用并且必须使用第一个方法属性来自定义部分,而不是实例化部分。
最后,学习OOP中的抽象,它可能会为您带来更多帮助。希望对您有所帮助:)
答案 3 :(得分:0)
接口的想法是让不同的类实现该接口,并且调用者无需知道(或关心)接口是哪个。
再举一个例子,以Java的OutputStream为例。它是一个抽象类(因此比实际接口要多一些“肉”或逻辑),但是主要思想是相同的。在您的程序中,您可以写入调用者传入的OutputStream。您只需要编写必须编写的内容即可。另一方面,调用者可以决定要处理的数据内容:通过网络发送该数据还是将其保存到file或pipe到另一个程序中? Zip还是encrypt之前这样做?调用方可以通过向您传递一个不同的OutputStream来实现此目的,并且您的代码无需更改即可处理网络I / O,压缩或加密。
测试可以通过ByteArrayOutputStream来捕获程序的输出。
答案 4 :(得分:0)
Vehicle c = new Car();
c.paint(); // <- THIS is the point of the latter format.
这种格式的重点是即使您不知道正在绘制哪种类型的paint
,也可以调用Vehicle
。
想象一下,您有ArrayList
个Vehicle
中的需要绘画。
ArrayList<Vehicles> vehicles = new ArrayList<>();
vehicles.add(new Car());
vehicles.add(new Jet());
vehicles.add(new Tank());
for(Vehicle vehicle : vehicles) {
vehicle.paint(); // <- This is the power, right here.
}
您肯定会不在该循环内调用sell
方法,因为它仅适用于Car
s(根据您的设计),而并非全部{ {1}}个。