Eli*_*ter 127 java oop abstract-class
为什么Object类是基于Java的基类,而不是抽象的?
我真的很长时间都有这个问题,这里纯粹是出于好奇而被问到这一点.我的代码或任何人的代码都没有破坏因为它不是抽象的,但我想知道为什么它们具体化了?
为什么有人想要这个Object类的"实例"(而不是它的存在,也就是引用)?一种情况是一个糟糕的同步代码,它使用一个Object的实例进行锁定(至少我用这种方式一次......我的坏).
是否有任何实际使用Object类的"实例"?它的实例化如何适合OOP?如果他们将其标记为抽象(当然在为其方法提供实现之后)会发生什么?
Gru*_*eck 65
如果没有设计师java.lang.Object告诉我们,我们必须根据意见做出答案.有几个问题可以提出来帮助清理它.
Object的任何方法都会受益于抽象吗?
可以说有些方法会从中受益.以hashCode()和equals()为实例,就可能有,如果他们俩都作了抽象一直围绕这两个复杂的挫折少了很多.这将要求开发人员弄清楚他们应该如何实现它们,使它们更加明显,它们应该是一致的(参见Effective Java).但是,我更多的意见是hashCode(),equals()并且clone()属于单独的选择性抽象(即接口).其他方法,wait(),notify(),finalize(),等有足够复杂和/或原产,所以最好他们已经实施,并不会被抽象受益.
所以我猜答案是否定的,Object的任何方法都不会从抽象中受益.
将Object类标记为抽象是否有益处?
假设所有方法都已实现,标记Object abstract的唯一效果是它无法构造(即new Object()编译错误).这会有好处吗?我认为术语"对象"本身就是抽象的(你能找到任何可以完全描述为"对象"的东西吗?),所以它适合面向对象的范式.然而,它是纯粹的一面.可以说,强制开发人员为任何具体的子类选择一个名称,即使是空子类,也会产生更好地表达其意图的代码.我认为,就范式而言,完全正确的是,对象应该被标记abstract,但是当它归结为它时,没有真正的好处,这是设计偏好的问题(实用主义与
使用普通对象进行同步的做法是否具有足够的理由使其具体化?
许多其他答案谈论构造一个在synchronized()操作中使用的普通对象.虽然这可能是一种常见且被接受的做法,但我不认为如果设计师希望将对象抽象化,那将是一个足够好的理由.其他答案已经提到我们如何在我们想要在某个对象上同步时声明Object的单个空子类,但是这并没有站起来 - SDK中可以提供一个空子类(java.lang.Lock或者其他) ,可以在我们想要同步的任何时候构建.这样做可以产生更强大的意图声明.
是否有任何其他因素可以通过使对象抽象而受到不利影响?
有几个区域,与纯粹的设计观点分开,可能影响了选择.不幸的是,我对他们的了解并不充分.但是,如果其中任何一项对决定产生影响,我不会感到惊讶:
还有其他原因吗?
有人提到它可能与反思有关.但是,在设计Object之后引入了反射.因此,它是否影响反射是没有实际意义的 - 这不是原因.对于泛型一样.
java.lang.Object也是人类设计的令人难忘的观点:他们可能犯了一个错误,他们可能没有考虑过这个问题.没有没有缺陷的语言,这可能是其中之一,但如果是,它就不是一个大问题了.而且我认为我可以肯定地说,在不缺乏野心的情况下,我不太可能参与设计这种广泛使用的技术的关键部分,特别是那个持续15年(?)并仍然强劲的技术,所以这个不应该被视为批评.
话虽如此,我会把它变成抽象的;-p
总结
基本上,据我所知,两个问题的答案"为什么java.lang.Object具体?" 或者(如果是这样)"为什么java.lang.Object是抽象的?" 是......"为什么不呢?"
Wim*_*dse 24
普通实例java.lang.Object通常用于锁定/同步方案,这是公认的惯例.
另外 - 它是抽象的原因是什么?因为它作为一个实例本身并不完全正常?它真的可以用一些抽象的成员吗?不要这么认为.因此,首先使其成为抽象的论点是不存在的.所以事实并非如此.
采用经典的动物等级,你有一个抽象的类Animal,使Animal类抽象的原因是因为动物的一个实例实际上是一个"无效的" - 缺乏一个更好的词 - 动物(即使它的所有方法都提供了基础实施).有Object,事实并非如此.首先要让它抽象化是没有压倒性的.
Bre*_*iel 11
我可以想到几个实例Object有用的情况:
equals除了实例本身外,它总是返回false.nulls 来填充集合或数组是最容易的.Object o = new Object() {...code here...}Blu*_*eft 10
从我读过的所有内容来看,似乎Object 不需要具体,事实上应该是抽象的.
它不仅没有必要具体,而且经过一些阅读后我确信Object 不抽象与基本继承模型冲突 - 我们不应该允许具体类的抽象子类,因为子类只应该添加功能.
显然,在Java中并非如此,我们有抽象的子类Object.
小智 7
我认为它可能应该被声明为抽象的,但是一旦完成并发布它就很难撤消而不会造成很大的痛苦 - 参见Java语言规范13.4.1:
"如果将不是抽象的类更改为声明为抽象,那么尝试创建该类的新实例的预先存在的二进制文件将在链接时抛出InstantiationError,或者(如果使用反射方法)在运行时抛出InstantiationException因此,不建议对广泛分布的课程进行这样的改变."
有时你需要一个没有自己状态的普通对象.尽管这些物体一见钟情似乎毫无用处,但它们仍具有实用性,因为每个物体都具有不同的身份.Tnis在几种情况下很有用,其中最重要的是锁定:你想要协调两个线程.在Java中,您可以使用将用作锁的对象来完成此操作.对象不需要任何状态它只是存在就足以成为一个锁:
class MyThread extends Thread {
private Object lock;
public MyThread(Object l) { lock = l; }
public void run() {
doSomething();
synchronized(lock) {
doSomethingElse();
}
}
}
Object lock = new Object();
new MyThread(lock).start();
new MyThread(lock).start();
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我们使用了一个锁来防止两个线程同时执行 doSomethingElse()
如果Object是抽象的并且我们需要一个锁,我们必须将它子类化而不添加任何方法或字段,以便我们可以实例化锁.
想想它,这是你的双重问题:假设对象是抽象的,它会定义任何抽象方法吗?我猜答案是否定的.在这种情况下,将类定义为抽象没有多大价值.
我不明白为什么大多数人似乎相信制作一个功能齐全的类,它以完全抽象的方式实现其所有方法都是一个好主意.
我宁愿问为什么要把它抽象化?它有什么不应该做的吗?它缺少一些应该具备的功能吗?这两个问题都可以用no来回答,它本身就是一个完全可以工作的类,使它抽象化只会导致人们实现空类.
public class UseableObject extends AbstractObject{}
Run Code Online (Sandbox Code Playgroud)
UseableObject继承自抽象Object,令人惊讶它可以实现,它不添加任何功能,它唯一的存在理由是允许访问Object公开的方法.
另外,我不同意在"差"同步中的使用.使用私有对象来同步访问比使用synchronize(this)更安全,并且比java util concurrent中的Lock类更安全且更易于使用.
| 归档时间: |
|
| 查看次数: |
12793 次 |
| 最近记录: |