0

在 C++ 中,可以更改重写方法的可见性。我发现这个功能有时非常有用,例如:

考虑您希望一个类具有一些调试方法,但您不希望它们作为公共类接口可见。你可以有类似的东西:

class IDebuggable {
public:
 virtual void debug(std::string s) = 0;
};

class MyProductionClass: public IDebuggable

public:
 void myClassMethod() {}

private:
 virtual void debug(std::string) {
  // do some debug here
 }

};

为此,当使用 MyProductionClass 类的对象时,我只能访问 MyProductionClass::myClassMethod()(生产接口)。

但是,如果我想使用它的调试功能,我可以这样做:

MyProductionClass* obj = new MyProductionClass();
IDebuggable* iface = obj;

iface->debug("Hello World");

根据我的经验,我发现这个“功能”非常有用。在 java 中这是不可能的,因为禁止更改继承方法的可见性。有没有另一种方法可以实现上述神器?

非常感谢

4

5 回答 5

2

就个人而言,我讨厌人们以这种方式改变方法的可见性。我认为为外部用户保留可见性并公开接口而不是类本身要好得多。喜欢:

class MyInterface {...}
class MyDebugable {...}

class MyClass : MyInterface, MyDebugable {...}

给内部MyInterface的用户和用户MyClass

通过更改可见性,您违反了Liskov substitution principle. 同时,您的用户仍然可以转换IDebuggable并调用您的“私有”方法

于 2013-05-17T15:36:53.113 回答
2

您不能降低继承方法的可见性。这是正确的。但是,您可以根据需要创建任意数量的接口,并让您类来实现这些接口。然后,如果您的客户端使用特定接口,它“无权访问”其他甚至公共方法。

这是一个例子。

public interface Foo {
    public void foo();
} 

public interface Bar {
    public void bar();
} 

public class MyClass implements Foo, Bar {
    public void foo() {}
    public void bar() {}
}

下面是我们如何使用这个类:

Foo f = new MyClass();

你可以foo()在这里打电话,不能打电话bsar()。但是,您可以Foo转换为Bar然后使用bar()方法。

于 2013-05-17T15:43:39.553 回答
1

在 Java 中,您可以增加方法的可见性,但不能在子类化时减少它。这是因为您可以通过父类(接口)访问对象,并且父类中定义的所有方法都应该可供调用者使用。

所以以下是可能的:

class A {
    protected void foo() {}
}

class B extends A {
    @Override
    public void foo() {}
}
于 2013-05-17T15:44:16.793 回答
0

像这样实现特征发现:

class A {

    public final T <T> lookup(Class<T> klazz) {
        return map.get(klazz);
    }

    public A() {
        map.put(IDebugable.class, new IDebuggable() { ... };
    }
}

A a = ...;
a.lookup(IDebuggable.class).debug();
于 2013-05-17T15:53:33.513 回答
0

这(看在上帝的份上)在 Java 中是不可能的。此外,通过使用具有不同配置的日志框架进行开发/生产,可以更好地实现您想要的。

于 2013-05-17T15:40:07.773 回答