天道酬勤,学无止境

在声明(.NET)中强制使用接口而不是具体实现(Force the use of interface instead of concrete implementation in declaration (.NET))

问题

在 C++ 中,您可以执行以下操作:

class base_class
{
public:
    virtual void do_something() = 0;
};

class derived_class : public base_class
{
private:
    virtual void do_something()
    {
        std::cout << "do_something() called";
    }
};

derived_class覆盖方法do_something()并使其成为private 。 效果是,调用此方法的唯一方法是这样的:

base_class *object = new derived_class();
object->do_something();

如果将对象声明为derived_class类型,则不能调用该方法,因为它是私有的:

derived_class *object = new derived_class();
object->do_something(); 
// --> error C2248: '::derived_class::do_something' : cannot access private member declared in class '::derived_class'  

我认为这很好,因为如果您创建一个用作接口的抽象类,您可以确保没有人不小心将字段声明为具体类型,但始终使用接口类。

由于通常在 C#/.NET 中,在重写方法时不允许将访问范围从public缩小到private ,有没有办法在这里实现类似的效果?

回答1

如果你显式地实现一个接口,这至少会鼓励人们在声明中使用接口类型。

interface IMyInterface
{
    void MyMethod();
}

class MyImplementation : IMyInterface
{
    void IMyInterface.MyMethod()
    {
    }
}

只有在将实例转换为IMyInterface后才能看到 MyMethod 。 如果声明使用接口类型,则在后续使用中不需要强制转换。

关于显式接口实现的 MSDN 页面(感谢 Luke,为我节省了几秒钟的时间^^)

IMyInterface instance = new MyImplementation();
instance.MyMethod();

MyImplementation instance2 = new MyImplementation();
instance2.MyMethod();  // Won't compile with an explicit implementation
((IMyInterface)instance2).MyMethod();
回答2

您也可以在 .Net 世界中执行此操作,使用显式接口实现

例如,BindingList<T> 实现了 IBindingList,但您必须将其强制转换为IBindingList才能看到该方法。

回答3

可以通过将方法标记为new来降低其可用性。

来自 MSDN 的 CA2222 的示例:不要降低继承的成员可见性:

using System;
namespace UsageLibrary
{
    public class ABaseType
    {
        public void BasePublicMethod(int argument1) {}
    }
    public class ADerivedType:ABaseType
    {
        // Violates rule: DoNotDecreaseInheritedMemberVisibility.
        // The compiler returns an error if this is overridden instead of new.
        private new void BasePublicMethod(int argument1){}       
    }
}

作为一项学术练习,这确实更有趣; 如果您的代码确实依赖于无法在 ADerivedType 上调用BasePublicMethodADerivedType这是一个可疑设计的警告信号。

回答4

如果实施此策略,问题在于该方法不是真正私有的。 如果您要向上转换对base_class的引用,那么该方法现在是公开的。 由于它是一个虚拟方法,因此用户代码将执行derived_class::do_something()即使它被标记为私有。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 强制子类在抽象 java 类中包含常量(force subclasses to include constant in abstract java class)
    问题 我有一个抽象类,我希望所有子类都根据实现定义一个常量——它主要是关于类实现的元数据。 在超类中: protected static final String OBJECT_NAME; protected static final String OBJECT_DEF; 然后在子类中: protected static final String OBJECT_NAME = "awesome class"; protected static final String OBJECT_DEF = "an awesome class that is also great"; 有没有办法强制类的实现声明一个常量? 回答1 您可以强制子类定义一个方法,该方法可以是该类的常量。 protected abstract String objectName(); protected abstract String objectDef(); 注意:如果您有子类的子类,它们可能会“忘记”覆盖这些方法。 回答2 这是另一种方法。 我喜欢它,因为它很严格,让我们可以将大部分代码(包括 getter)放入父类中,使其子类保持整洁。 abstract class Parent { private final int age; private final String name; Parent(int age
  • 如何在没有抽象基类的情况下强制在后代中重写方法?(How to force overriding a method in a descendant, without having an abstract base class?)
    问题 问题标题似乎有点让人困惑,但是我会在这里尝试清除我的问题。 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { public abstract class Employee { private string name; private int empid; BenefitPackage _BenefitPackage = new BenefitPackage(); public string Name { get { return this.name; } set { this.name = value; } } public int EmpId { get { return this.empid; } set { if (value == 1) return; this.empid = value; } } public Employee(string Name, int EmpId) { this.Name = Name; this.EmpId = EmpId; } public Employee() { } public abstract void GiveBonus(); }
  • 是否可以在 C# 中强制接口实现为虚拟?(Is it possible to force an interface implementation to be virtual in C#?)
    问题 我今天遇到了一个问题,试图覆盖尚未声明为虚拟的接口方法的实现。 在这种情况下,我无法更改接口或基本实现,必须尝试其他方法,但我想知道是否有办法强制类使用虚拟方法实现接口。 例子: interface IBuilder<T> { // Already implicitly virtual /*virtual*/ T Build(); } // This is a class written by someone else class SimpleBuilder: IBuilder<SomeObject> { // I would like to force this to be virtual public SomeObject Build() { return new SomeObject(); } } // This is the class I am writing. class CustomBuilder: SimpleBuilder { public /*override*/ SomeObject Build() { var obj = base.Build(); obj.ModifyInSomeWay(); return obj; } } 编辑: CustomBuilder旨在与 MEF 一起使用,因此我从SimpleBuilder派生,以便 MEF 解析正确的类型
  • 强制继承链的每个类覆盖抽象方法(Force every class of an inheritance chain to override an abstract method)
    问题 假设我有一个继承链,其中每个类通过添加一个新字段来扩展其超类,并且我希望该链的每个类都覆盖toString()方法,如下所示: public String toString() { return super.toString() + "[newfield=" + newfield + "]"; } 如果我使用抽象基类,那么当继承链的一个类通过实现抽象方法变得具体时,从那时起所有子类也通过继承已经实现的方法变得具体。 Java 中有没有办法强制每个类覆盖(重新实现)抽象方法,即使它已经在继承链的更高层实现了? 回答1 简短的回答:没有。 长答案:您可以编写一个单元测试来扫描类路径(为此使用类似反射的库),加载抽象类的每个子类并使用反射检查方法。 但是在编译时没有办法做到这一点。 除了Java,AspectJ 有一个hasMethod()切入点,它可以为你做检查,但不幸的是,它只对declare parents建议有效。 也许您可以使用 aspectj 分两步完成: 定义一个接口IllBehaved 。 定义一个建议,将此接口分配给从您的基类扩展但没有成员的类然后为实现此接口的所有类型声明编译错误pointcut isSubTypeOfYourClass(): within(com.your.BaseClass+); pointcut overridesMethod()
  • C#接口。 隐式实现与显式实现(C# Interfaces. Implicit implementation versus Explicit implementation)
    问题 在C#中隐式和显式实现接口有何区别? 什么时候应该使用隐式,什么时候应该使用显式? 彼此之间是否有优点和/或缺点? Microsoft的官方指南(来自第一版Framework Design Guidelines)指出,不建议使用显式实现,因为它会给代码带来意想不到的行为。 我认为,在您未将事物作为接口传递的情况下,该指南在IoC之前非常有效。 有人也可以谈谈这方面吗? 回答1 隐式是当您通过类中的成员定义接口时。 显式的是您在接口上的类中定义方法时。 我知道这听起来很混乱,但这就是我的意思: IList.CopyTo将隐式实现为: public void CopyTo(Array array, int index) { throw new NotImplementedException(); } 并明确表示为: void ICollection.CopyTo(Array array, int index) { throw new NotImplementedException(); } 区别在于隐式实现允许您通过将接口强制转换为该类以及接口本身来创建的类来访问该接口。 显式实现允许您仅通过将其强制转换为接口本身来访问该接口。 MyClass myClass = new MyClass(); // Declared as concrete class myclass
  • 接口和抽象类之间有什么区别?(What is the difference between an interface and abstract class?)
    问题 接口和抽象类之间到底有什么区别? 回答1 介面 接口是一种契约:编写接口的人说:“嘿,我接受那样的事情”,而使用接口的人说:“好,我编写的类看起来就这样”。 接口是一个空壳。 这些方法只有签名,这意味着这些方法没有主体。 该界面无法执行任何操作。 这只是一个模式。 例如(伪代码): // I say all motor vehicles should look like this: interface MotorVehicle { void run(); int getFuel(); } // My team mate complies and writes vehicle looking that way class Car implements MotorVehicle { int fuel; void run() { print("Wrroooooooom"); } int getFuel() { return this.fuel; } } 实施一个接口消耗的CPU很少,因为它不是一个类,而是一堆名称,因此不需要执行任何昂贵的查找。 当它很重要时,例如在嵌入式设备中,它很棒。 抽象类 与接口不同,抽象类是类。 它们的使用成本更高,因为从它们继承后需要进行查找。 抽象类看起来很像接口,但是它们还有更多的功能:您可以为它们定义一个行为。 与其说是一个人,不如说是
  • 接口中的toString(),equals()和hashCode()(toString(), equals(), and hashCode() in an interface)
    问题 因此,我有一个带有一堆需要实现的方法的接口,这些方法的名称无关紧要。 实现此接口的对象通常放入集合中,并且具有我希望它们使用的特殊toString()格式。 因此,我认为将hashCode(),equals()和toString()放入接口会很方便,以确保我记得重写这些默认方法。 但是,当我将这些方法添加到接口中时,即使我没有明确实现这三个方法,IDE / Compiler也不会抱怨,即使我将它们明确地放在接口中也是如此。 为什么不为我强制执行此操作? 它抱怨如果我没有实现其他任何方法,但是它没有强制执行这三个方法。 是什么赋予了? 有什么线索吗? 回答1 Java中的所有对象都继承自java.lang.Object而Object提供了这些方法的默认实现。 如果您的接口包含其他方法,则Java会抱怨您没有通过提供这些方法的实现来完全实现该接口。 但是对于equals() , hashCode()和toString() (以及您未提到的其他一些),实现已经存在。 您可能能够实现所需目标的一种方法是,在接口中提供不同的方法,例如toPrettyString()或类似的方法。 然后,您可以调用该方法,而不是默认的toString()方法。 回答2 听起来您想强制类重写这些方法的默认实现。 如果是这样,执行此操作的方法是声明一个抽象超类,该类具有声明为abstract的方法。 例如:
  • 何时使用IList和何时使用List(When to use IList and when to use List)
    问题 我知道IList是接口,而List是具体类型,但我仍然不知道何时使用每个接口。 我现在正在做的是,如果我不需要使用接口的Sort或FindAll方法。 我对吗? 有没有更好的方法来决定何时使用接口或具体类型? 回答1 我遵循两个规则: 接受将起作用的最基本的类型返回用户需要的最丰富的类型 因此,在编写要使用集合的函数或方法时,请不要将其写入列表,而要写入IList <T>,ICollection <T>或IEnumerable <T>。 即使System.Object也可以是T,所以通用接口即使对于异构列表也仍然可以使用。 如果您决定在以后使用堆栈或其他一些数据结构,这样做将使您免于头痛。 如果您只需要遍历该函数,则IEnumerable <T>实际上就是您所需要的。 另一方面,当从函数中返回对象时,您希望为用户提供尽可能丰富的操作集,而不必进行操作。 因此,在这种情况下,如果内部是List <T>,则将副本作为List <T>返回。 回答2 FxCop检查的Microsoft准则不建议在公共API中使用List <T>-最好使用IList <T>。 顺便说一句,我现在几乎总是将一维数组声明为IList <T>,这意味着我可以始终使用IList <T> .Count属性而不是Array.Length。 例如: public interface IMyApi { IList
  • 避免实现接口中存在的方法 - java(avoid implementation of a method which is there in interface - java)
    问题 我有一个如下所示的界面: public interface a { public void m1(); public void m2(); public void m3(); } public class A implements a { public void m3() { // implementation code } } 我想避免实现方法的其余部分。 一种方法是拥有所有方法而不在试图实现interface的类中实现。 我如何避免这种情况。 示例代码将帮助我更好地理解:) 回答1 public interface a{ public void m1(); public void m2(); public void m3(); } public abstract class A implements a{ public void m3(){ // implementation code } } 声明为抽象类,因此您不需要在此类中实现这些方法。 但是你必须在具体的类中实现这些方法 回答2 TLDR; If the interface is given to you, then you have no choice. The creator of the interface forces you to implement all of its methods. If you
  • 风格上的差异:IDictionary与Dictionary(A difference in style: IDictionary vs Dictionary)
    问题 我有一个朋友,在使用Java开发了很长一段时间后才开始从事.NET开发,在看了他的一些代码之后,我注意到他经常做以下事情: IDictionary<string, MyClass> dictionary = new Dictionary<string, MyClass>(); 他将字典声明为接口而不是类。 通常,我会执行以下操作: Dictionary<string, MyClass> dictionary = new Dictionary<string, MyClass>(); 我只会在需要时使用IDictionary接口(例如,将字典传递给接受IDictionary接口的方法)。 我的问题是:他的做事方式有什么好处吗? 这是Java的惯例吗? 回答1 如果IDictionary是比Dictionary更通用的类型,则在声明变量时使用更通用的类型是有意义的。 这样,您不必太在乎分配给变量的实现类,并且将来可以轻松更改类型,而无需更改大量后续代码。 例如,在Java中,通常认为做起来更好 List<Integer> intList=new LinkedList<Integer>(); 比要做的事 LinkedList<Integer> intList=new LinkedList<Integer>(); 这样,我确定所有下面的代码都将列表视为List而不是LinkedList
  • 接口 vs 抽象类(一般面向对象)(Interface vs Abstract Class (general OO))
    问题 我最近接受了两次电话采访,被问及 Interface 和 Abstract 类之间的区别。 我已经解释了我能想到的每一个方面,但他们似乎在等我说一些具体的东西,我不知道是什么。 根据我的经验,我认为以下是正确的。 如果我遗漏了一个主要观点,请告诉我。 界面: 在接口中声明的每个方法都必须在子类中实现。 接口中只能存在事件、委托、属性 (C#) 和方法。 一个类可以实现多个接口。 抽象类: 只有抽象方法必须由子类实现。 抽象类可以具有带有实现的普通方法。 除了事件、委托、属性和方法之外,抽象类还可以有类变量。 由于C#中不存在多重继承,一个类只能实现一个抽象类。 毕竟,面试官提出了一个问题“如果你有一个只有抽象方法的抽象类怎么办?那与接口有什么不同?” 我不知道答案,但我认为这是上面提到的继承,对吗? 另一位面试官问我,如果接口中有一个 Public 变量会怎样,这与抽象类中有什么不同? 我坚持认为接口中不能有公共变量。 我不知道他想听什么,但他也不满意。 另见: 何时使用接口而不是抽象类,反之亦然接口与抽象类你如何决定使用抽象类和接口? 接口和抽象类有什么区别? 回答1 打个比方吧:当我在空军的时候,我去接受飞行员训练,成为了一名 USAF(美国空军)飞行员。 那时我没有资格飞行任何东西,不得不参加飞机类型培训。 获得资格后,我是一名飞行员(抽象班)和 C-141 飞行员
  • 为类或接口声明IDisposable?(Declare IDisposable for the class or interface?)
    问题 从以下情况开始: public interface ISample { } public class SampleA : ISample { // has some (unmanaged) resources that needs to be disposed } public class SampleB : ISample { // has no resources that needs to be disposed } SampleA类应实现IDisposable接口,以释放资源。 您可以通过两种方式解决此问题: 1.将所需的接口添加到类SampleA中: public class SampleA : ISample, IDisposable { // has some (unmanaged) resources that needs to be disposed } 2.将它添加到接口ISample中,并强制派生类实现它: public interface ISample : IDisposable { } 如果将其放入接口,则即使没有任何可设置的内容,也将强制任何实现实现IDisposable。 另一方面,很清楚地看到,接口的具体实现需要一个处理/使用块,并且不需要将其强制转换为IDisposable即可进行清理。 两种方式可能都有其他优点/缺点
  • 为什么我不能在 Java 接口中定义静态方法?(Why can't I define a static method in a Java interface?)
    问题 编辑:从 Java 8 开始,接口中现在允许使用静态方法。 这是示例: public interface IXMLizable<T> { static T newInstanceFromXML(Element e); Element toXMLElement(); } 这当然行不通。 但为什么不呢? 可能的问题之一是,当您致电时会发生什么: IXMLizable.newInstanceFromXML(e); 在这种情况下,我认为它应该只调用一个空方法(即 {})。 所有子类都将被强制实现静态方法,因此在调用静态方法时它们都可以。 那为什么这不可能呢? 编辑:我想我正在寻找比“因为这就是 Java 的方式”更深入的答案。 静态方法不能被覆盖是否有特定的技术原因? 也就是说,为什么 Java 的设计者决定使实例方法可覆盖而不是静态方法? 编辑:我的设计的问题是我试图使用接口来强制执行编码约定。 也就是说,接口的目标是双重的: 我希望 IXMLizable 接口允许我将实现它的类转换为 XML 元素(使用多态,工作正常)。 如果有人想要创建一个实现 IXMLizable 接口的类的新实例,他们将始终知道会有一个 newInstanceFromXML(Element e) 静态构造函数。 除了在界面中添加评论之外,还有其他方法可以确保这一点吗? 回答1 Java 8 允许静态接口方法
  • 入门语言JavaSE基础
    面向对象继承:继承是从已有的类中得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类,基类);得到继承信息的类被称为子类(派生类)。继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序中可变因素的重要手段。封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只是向外界提供最简单的编程接口。多态性:多态性是指允许不同子类类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。如果将对象的方法视为对象向外界提供服务的方式,但一切对A系统来说都是透明的。方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称后绑定)。运行时的多态时面向对象最精髓的东西,要实现多态需要做两件事:1.方法重写(子类继承父类并重写父类中已有的或抽象的方法);2.对象造型(用父类型的引用引用子类型对象,这样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。抽象:抽象是将一类对象的共同特征总结出来构造类的过程
  • 我们应该@Override接口的方法实现吗?(Should we @Override an interface's method implementation?)
    问题 实现接口方法的方法是否应使用@Override进行注释? Override注释的Javadoc说: 指示方法声明旨在覆盖超类中的方法声明。 如果使用此注释类型对方法进行注释但未覆盖超类方法,则要求编译器生成错误消息。 我不认为接口从技术上讲是超类。 还是吗? 问题阐述 回答1 您应该尽可能使用@Override。 它可以防止犯下简单的错误。 例子: class C { @Override public boolean equals(SomeClass obj){ // code ... } } 这不会编译,因为它没有正确覆盖公共布尔equals(Object obj)。 实现接口(仅限1.6及更高版本)或重写Super类的方法的方法也是如此。 回答2 我相信javac的行为已经改变-1.5禁止注释,而1.6则没有。 批注提供了额外的编译时检查,因此如果您使用的是1.6,我会去做的。 回答3 如果可用,应始终使用@Override注释方法。 在JDK 5中,这意味着重写超类的方法;在JDK 6和7中,这意味着重写超类的方法以及实现接口的方法。 如前所述,其原因是它允许编译器在您认为您覆盖(或实现)方法但实际上定义了新方法(不同签名)的地方捕获错误。 equals(Object) vs. equals(YourObject)示例是一个标准案例,但是可以为接口实现提供相同的参数。
  • 接口的好案例(Good Case For Interfaces)
    问题 我在一家公司工作,有些公司要求在我们的代码(Visual Studio C#3.5)中使用接口是合理的。 我想问一个需要接口的铁定论。 (我的目标是证明接口是编程的正常部分。) 我不需要说服力,我只需要一个很好的论据就可以说服他人。 我要查找的参数类型是基于事实的,而不是基于比较的(即“因为.NET库使用它们”是基于比较的。) 因此,针对它们的争论是:如果正确地设置了一个类(使用其公共和私有成员),则接口只是额外的开销,因为使用该类的接口仅限于公共成员。 如果您需要一个由多个类实现的接口,则只需设置继承/多态即可。 回答1 代码解耦。 通过对接口进行编程,您可以将使用接口的代码与实现接口的代码解耦。 这使您可以更改实现,而不必使用它重构所有代码。 这与继承/多态性一起工作,使您可以互换使用许多可能的实现中的任何一种。 模拟和单元测试。 当方法为虚拟方法时,最容易使用模拟框架,而默认情况下,这些方法是通过接口获得的。 这实际上是我创建接口的最大原因。 定义可能适用于许多不同类的行为,即使它们之间没有关系(除了定义的行为),也可以互换使用它们。 例如,“马”和“自行车”类可能都具有“骑乘”方法。 您可以定义一个接口IRideable,该接口定义Ride行为,并且使用此行为的任何类都可以使用Horse或Bicycle对象,而不必强制它们之间的不自然继承。 回答2 因此
  • 有没有办法在 .Net 中声明一个实现多个接口的变量?(Is there a way to declare a variable that implements multiple interfaces in .Net?)
    问题 类似于这个Java问题。 我想指定一个变量实现多个接口。 例如 private {IFirstInterface, ISecondInterface} _foo; public void SetFoo({IFirstInterface, ISecondInterface} value) { _foo = value; } 要求: 我无法为大多数将传递给 Foo 的类型添加接口。 所以我不能创建从 IFirstInterface 和 ISecondInterface 继承的第三个接口。 如果可能,我想避免将包含类设为泛型,因为 Foo 的类型与类没有太大关系,而且用户在编译时不太可能知道它。 稍后我需要使用 foo 来访问两个接口中的方法。 我想以编译器安全的方式执行此操作,即在尝试使用它之前不要尝试强制转换到接口。 如果 foo 没有实现这两个接口,相当多的功能将无法正常工作。 这可能吗? 编辑:由于各种原因,我多次想要这个。 在这种情况下,这是因为我将一组属性从 ObservableCollections 更改为 ReadOnlyObservableCollections。 我有一个助手类,它创建从源 ObservableCollection 到另一个集合的投影。 由于 ReadOnlyObservableCollection 不是从
  • 如何在Java中强制进行垃圾回收?(How to force garbage collection in Java?)
    问题 即使很棘手,也可以用Java强制进行垃圾回收吗? 我知道System.gc(); 和Runtime.gc(); 但他们只建议使用GC。 我该如何强制GC? 回答1 最好的选择是调用System.gc(),这只是向垃圾收集器提示您要它进行收集。 由于垃圾收集器是不确定的,因此无法强制立即收集。 回答2 jlibs库具有用于垃圾回收的良好实用程序类。 您可以使用带有WeakReference对象的漂亮技巧来强制进行垃圾收集。 jlibs中的RuntimeUtil.gc(): /** * This method guarantees that garbage collection is * done unlike <code>{@link System#gc()}</code> */ public static void gc() { Object obj = new Object(); WeakReference ref = new WeakReference<Object>(obj); obj = null; while(ref.get() != null) { System.gc(); } } 回答3 强制GC的最佳方法(如果不是唯一的话)是编写自定义JVM。 我相信垃圾收集器是可插入的,因此您可能只选择其中一种可用的实现并进行调整即可。 注意:这不是一个简单的答案。 回答4
  • 强制一个类重写.equals方法(Force a class to override the .equals method)
    问题 我有一堆实现通用接口的类:命令。 这节课去了一张地图。 为了使Map正常工作,我需要实现Command的每个类都重写Object.equals(Object other)方法。 没关系。 但是我想强迫压倒一切。 =>当执行命令的某些对象不覆盖相等时,将发生编译错误。 那有可能吗? 编辑:顺便说一句,我还需要强制覆盖哈希码... 回答1 不,你不能。 但是,您可以做的是使用抽象基类而不是接口,并使equals()抽象: abstract class Command { // put other methods from Command interface here public abstract boolean equals(Object other); public abstract int hashCode(); } 然后, Command子类必须提供自己的equals和hashCode方法。 强迫API用户扩展基类通常是一种不好的做法,但在这种情况下可能是有道理的。 此外,如果你让Command的抽象基类,而不是一个接口,而不是除了命令接口引入人造基类,那么就没有犯错的API的用户的风险。 回答2 您可以从抽象的XObject而不是java.lang.Object扩展对象吗? public abstract class XObject extends Object {
  • 如何强制在抽象类的所有子类中定义构造函数(How can I force a Constructor to be defined in all subclass of my abstract class)
    问题 我有一个定义抽象方法的抽象类A。 这意味着,要使一个类变得可实例化,必须实现所有抽象方法。 我希望我的所有子类都实现一个以2个整数作为参数的构造函数。 声明构造函数违背了我的目的,因为我希望在子类中定义构造函数,而我对实现一无所知。 而且,我不能将构造函数声明为抽象的。 有没有办法做到这一点 ? 我想要的例子: 可以说我正在定义Matrix类的API。 在我的问题中,Matrix无法更改其尺寸。 对于要创建的矩阵,我需要提供其大小。 因此,我希望所有实现者都将大小作为参数提供给构造函数。 该构造函数是由问题驱动的,而不是由实现问题引起的。 只要保留方法的所有语义,该实现就可以用它们做任何想要的事情。 假设我想在我的抽象类中提供invert()方法的基本实现。 此方法将创建一个具有this反向尺寸的新矩阵。 更具体地说,正如在抽象类中定义的那样,它将使用一个带有两个int的构造函数来创建与this相同的类的新实例。 因为它不知道实例,所以它将使用反射(getDefinedConstructor),并且我想要一种方法来保证我将得到它,并且它将对实现有意义。 回答1 您不能在子类中强制使用构造函数的特定签名,但是可以强制其通过抽象类中的构造函数并使用两个整数。 子类可以从无参数构造函数中调用该构造函数,例如,传入常量。 那是您可以找到的最接近的。 而且,正如您所说,您对实现一无所知