简体   繁体   English

超类的子方法(java)

[英]Child method from superclass (java)

I have a superclass, let's say BaseClass and two subclasses, let's say SubclassA and SubclassB , they don't have any other relationship between them but their parent class. 我有一个超类,比如说BaseClass和两个子类,比如说SubclassASubclassB ,它们之间没有任何其他关系,但它们的父类却没有其他关系。

At a lot of places in my code I need to call to methods that both the subclasses have but not the parentclass... And I find myself repeating a lot of code which looks like: 在代码的很多地方,我需要调用两个子类都具有但父类都没有的方法...而且我发现自己在重复很多代码,如下所示:

if (obj instanceof SubclassA) {
// stuff
} else if (obj instanceof SubclassB) {
// same stuff
}

The first idea should be to put that "stuff" into a method in superclass, but I can't as that superclass is parent to other subclasses that don't have that behavior... 第一个想法应该是将“东西”放入超类的方法中,但我不能这样做,因为该超类是其他没有该行为的子类的父类...

So... is there a way to avoid repeating aaaalll of that code? 那么...有办法避免重复该代码的aaaalll吗?

Maybe a common superclass for both subclasses that is a subclass itself of superclass? 也许这两个子类都有一个共同的超类,它本身就是超类的子类?

I would suggest extracting the method as an abstract method in the parent(if the parent is abstract), or just a method that will be overridden in child classes. 我建议将方法提取为父方法中的抽象方法(如果父方法是抽象方法),或者只是将在子类中重写的方法。 If this is not possible, or desirable I would suggest adding a common abstract class that extends the parent that has just the method that is common to both subclasses, that will be then extended by the two subclasses. 如果这是不可能的,或者不希望这样做,我建议添加一个公共的抽象类,以扩展父类,该父类具有两个子类都通用的方法,然后再由这两个子类进行扩展。

If adding and changing the parent class might be an issue, you can do the same thing by using an interface that is then implemented by both subclasses and where you need to call your code you will just cast to the given interface and call the needed method. 如果添加和更改父类可能是一个问题,则可以通过使用两个子类都实现的接口来做同样的事情,在需要调用代码的地方,只需将其转换为给定的接口并调用所需的方法即可。 。

Something like this: 像这样:

interface CommonInterface {
   void commonMethod();
}

class SubClassB implements CommonInterface {
    void commonMethod() {
        // implementation
    }
}

class SubClassA implements CommonInterface {
    void commonMethod() {
       // implementation
    }
}

//...
if (obj instanceof CommonInterface) {
   ((CommonInterface)object).stuffCall();
} 

Add the method to the super class. 将方法添加到超类。
Make it with an empty body. 用一个空的身体。

In SubClassA override it, implement the logic you need. 在SubClassA中重写它,实现所需的逻辑。
In SubClassB override it, implement the logic you need. 在SubClassB中重写它,实现所需的逻辑。

Then in your calling code, instead of doing 然后在您的调用代码中,而不是这样做

if (obj instanceof SubclassA) {
    obj.method();
} else if (obj instanceof SubclassB) {
    obj.method();
}

just do this 只是这样做

obj.method();

provided obj is declared as an instance of the parent class. 提供的obj被声明为父类的实例。

The empty method body in the super class guarantees you have 超类中的空方法主体保证您拥有
no issues with this "but I can't as that super class is parent 对此没有问题“但是我不能,因为那个超类是父母
to other subclasses that don't have that behavior" . 到其他没有该行为的子类”

So the idea is that you will have empty behavior 所以这个想法是,你将有空洞的行为
in the super class and in all the sub classes which 在超类和所有子类中
do not explicitly override this method. 不要显式重写此方法。

What about the following two ways: 那么以下两种方式呢?

  1. Declare the target method in super class and provide a default implementation(eg empty method, do nothing) as well. 在超类中声明目标方法,并提供默认的实现(例如,空方法,什么也不做)。 Subclass will override that behavior if needed. 如果需要,子类将覆盖该行为。
  2. Declare the target method in a Interface, and make SubclassA and SubclassB implementation of the interface. 在接口中声明目标方法,并实现该接口的SubclassA和SubclassB实现。 The super class and other subclasses don't need to implement the interface. 父类和其他子类不需要实现该接口。

如果SubClassA和SubClassB具有某些在Subclass C,D,E等中不存在的行为,则只需在父级与A和B之间引入一个中间类。C,D等源自父级,而B源自新类,这包含A和B共享的功能。

Firstly, the concept of polymorphism is to do away with the need to check the type of an object before calling methods on it. 首先,多态性的概念是消除在调用对象的方法之前检查对象类型的需要。 So, this should not be necessary in an OO-language. 因此,在OO语言中这不必要。

Secondly, the reason why you might use an abstract parent class over an interface would but because there is some shared functionality between sub-types (subclasses). 其次,之所以可以在接口上使用抽象父类,是因为子类型(子类)之间存在某些共享功能。 So, if there is shared, common functionality between SubclassA and SubclassB then leave your superclass intact, otherwise switch it to an interface. 因此,如果SubclassASubclassB之间存在共享的通用功能,则保持超类完整,否则将其切换到接口。

Likewise, and as you suggest yourself, if SubclassA and SubclassB have a common behaviour (but their own implementation) then utilise a separate API (if other sub-types of BaseClass do not also share that behaviour (your #doStuff call). 同样,正如您所建议的那样,如果SubclassASubclassB具有相同的行为(但它们自己的实现),则使用单独的API(如果BaseClass其他子类型也没有共享该行为(您的#doStuff调用)。

In this case, I'd introduce interface Stuff containing method #doStuff and have both my SubclassA and SubclassB implement it, each providing it's own implementation. 在这种情况下,我将介绍包含方法#doStuff接口Stuff ,并让我的SubclassASubclassB实现它,每个都提供它自己的实现。 Your clients can then treat your obj instance as a Stuff , irrespective of it's real type and polymorphism will do the rest. 然后,您的客户可以将obj实例视为Stuff ,而不管它是实类型,多态将完成其余工作。

interface Stuff {
    void doStuff();
}

public class SubclassA extends BaseClass implements Stuff {
    // Does it need BaseClass still?
    public doStuff() {
        ...
    } 
}

public class SubclassB extends BaseClass implements Stuff {
    // Does it need BaseClass still?
    public doStuff() {
        ...
    } 
}

// Example client code...
public class MyStuffClient {

    Stuff s = new SubclassA();
    ...
    public void onStuff() {
        s.doStuff();
    } 
}

Decide if you really need the suer class BaseClass . 确定您是否真的需要suer类BaseClass

You can make the method on the superclass protected . 您可以将方法放在超类上成为protected For example, you can do this on SuperClass : 例如,您可以在SuperClass上执行此操作

package test;
public SuperClass {
   protected void myMethod() {
      ...stuff...
   }
}

exposing on SubclassA 暴露于SubclassA

package test;
public SubclassA extends SuperClass {
   public void myMethod() {
      super.myMethod();
   }
}

and hiding on SubclassB (just not override it) 并隐藏在SubclassB上 (只是不覆盖它)

package test;
public SubclassB extends SuperClass {
}

From a different package , protected methods are not visible unless the class override it changing its visibility modifier. 在不同的包中 ,除非类重写它的可见性修饰符,否则受保护的方法将不可见。

Source: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html 来源: http : //docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM