【问题标题】:Assignment operator and "this" keyword赋值运算符和“this”关键字
【发布时间】:2015-04-10 20:20:34
【问题描述】:

考虑以下代码sn-p:

class Parent {
    Parent() {
        this = new Child();
    }
}
class Child extends Parent { }

上面会抛出语法错误:The left hand side of an assignment operator must be a variable

在java中,this关键字存放的是当前调用对象的内存地址。我希望用类的子类的实例覆盖当前对象。我知道上面的 sn-p 会引发错误,因为 this 不是变量,可能是不可变的。

但是,我想知道为什么 java 不允许上述功能?有什么不好的地方吗?

编辑:这个问题是在参考自然语言处理 (NLP) 上下文时想到的。例如,在法语中,每个动词都必须以“er”、“ir”或“re”结尾。所有动词都有一定的共同特征。但是,每个动词都必须是上述三种类型中的一种。所以在父类“Verb”的构造函数中,我想将创建的对象分类为“ErVerb”、“IrVerb”或“ReVerb”。

【问题讨论】:

  • 这没有意义,即使这个特定的代码可以工作,它也会抛出 StackOverflowException。
  • 类如何知道它是子类?哪个还没有出生? :P
  • 您到底想达到什么目标?
  • 首先想到的是它是多么令人困惑。如果我创建一个Parent 对象,我希望它实际上是一个Parent 对象,而不是Child 对象。如果我想要一个Child 对象,我会明确地创建一个。
  • 你可能想拥有一个工厂:en.wikipedia.org/wiki/Factory_method_pattern

标签: java theory


【解决方案1】:

有两种情况:

如果您让this 被实例化为任何Object,不一定是类型层次结构中的一个,那么实例化将无法保证其引用的内容。这打破了一些东西,最明显的是面向对象编程的整个概念。

如果您将this 限制为实例化为父类的任何子类,则该子类构造函数将无限次调用父构造函数,从而导致StackOverflowError

【讨论】:

  • 当我提出这个问题时,我想到了你的第二种情况。如果在 Java 中不是强制每个子类都调用它的父类的构造函数,那么上面的 sn-p 可能吗?我从不喜欢 java 强制每个子类的构造函数调用父类的构造函数的事实。
  • 从面向对象的角度来看,删除子构造函数流会导致其他事情中断。对象状态需要严格维护,OO 规定每个父对象应该负责维护自己的状态,独立于其子类。这里还有一些需要考虑的事情——想象类 A 有孩子 B 和 C。假设在 A 的构造函数中你掷硬币并写了this = new B()this = new C()。直到运行时,您才能确定类型 - 但JVM 也不能。那么编译器能做什么呢?可以使用哪些方法?等等
【解决方案2】:

在父类的构造函数中构造子类实例并用创建的子实例替换实际的父类实例没有任何意义。

尽管在 cmets 和另一个答案中指出了令人讨厌的 StackOverflowError,但没有这样做的用例。一般来说,在创建父级的同时创建一个子级是荒谬的(从逻辑的角度来看)。

考虑以下推理

工厂正在组装一辆特定的汽车。组装特定汽车的过程包括许多步骤。

其中一些步骤仅在组装特定汽车时发生,而其他步骤则在组装特定汽车和组装其他车辆(例如特定货车)时发生。

现在让我们假设在组装许多车辆(包括特定汽车和特定货车)时发生的这些一般步骤之一表明我们必须组装一辆新的特定货车并让它成为普通车辆组装好了。

现在,我们正在组装的特定汽车将成为这辆新的特定货车。但汽车不可能是面包车 => ABSURD

【讨论】:

  • 这个问题是在参考自然语言处理 (NLP) 上下文时想到的。例如,在法语中,每个动词都必须以“er”、“ir”或“re”结尾。所有动词都有一定的共同特征。但是,每个动词都必须是上述三种类型中的一种。所以在父类“Verb”的构造函数中,我想将创建的对象分类为“ErVerb”、“IrVerb”或“ReVerb”。因此,这个功能对我来说似乎很有用。
  • 现在我明白你提出这个问题的动机了。但是,在 OO 设计中,层次关系不是这样建模的。您始终创建某个类的对象,并且在该对象不再存在之前保持不变。对象的类不是分类。您不能使用属性对类建模,例如法语动词的类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-15
  • 2011-11-16
  • 2018-03-22
  • 2013-06-28
  • 1970-01-01
  • 2015-03-19
  • 2021-08-10
相关资源
最近更新 更多