Java中的作用域或可见性约束是什么? 我从2000开始在java编程,而C++从1987开始。因此,大多数时候我可以很容易地用C++知识来帮助理解java概念。然而,在某些场合,它给我一个“文化”冲击(对于一个根植于C++文化的人)。如果我有以下C++程序: // override.cpp class Base { public: void f(int) { } }; class Derived : public Base { public: void f(char *) { } }; int main() { Derived d; d.f(5); // This line throws a compilation error }

Java中的作用域或可见性约束是什么? 我从2000开始在java编程,而C++从1987开始。因此,大多数时候我可以很容易地用C++知识来帮助理解java概念。然而,在某些场合,它给我一个“文化”冲击(对于一个根植于C++文化的人)。如果我有以下C++程序: // override.cpp class Base { public: void f(int) { } }; class Derived : public Base { public: void f(char *) { } }; int main() { Derived d; d.f(5); // This line throws a compilation error },java,c++,scope,Java,C++,Scope,通过派生对象d调用f(5)会引发错误,因为在派生类的范围内,f()只能接受字符指针。如果我把这个程序翻译成Java: // Override.java class Base { public void f(int i) { System.out.println("Base.f()"); } } class Derived extends Base { public void f(String s) { System.out.println("derived.f()"); }

通过派生对象d调用f(5)会引发错误,因为在派生类的范围内,f()只能接受字符指针。如果我把这个程序翻译成Java:

// Override.java
class Base
{
    public void f(int i) { System.out.println("Base.f()"); }
}

class Derived extends Base
{
    public void f(String s) { System.out.println("derived.f()"); }

    public static void main(String [] args)
    {
        Derived d = new Derived();
        d.f(5);
    }
}
编译器不会抛出任何错误,程序将生成以下输出:

Base.f()

这显然是误导。调用派生的作用域中不可用的函数时,我不应该得到编译错误吗?

在java中,非私有成员,如
public void f(int I)
将被子类继承,这意味着它将是子类的方法成员,因此

  • public void f(字符串s)
  • publicsvoidf(inti)

在子类中是可访问的。在C++中,

它不搜索基类来默认调用函数/方法。您需要通过关键字
using
like
using Base::f显式指定相同的值在您的情况下。但是在Java中,默认情况下是这样的。using语句将重载函数带入相同的范围,以便它可以参与重载解析。下面的C++代码对我来说很好。因此,区别仅在于默认行为

class Base
{
public:
   void f(int) { }
};

class Derived : public Base
{
public:
using Base::f; // this line allow you to use function from base class
   void f(char *) { }
};

int main()
{
   Derived d;
   d.f(5); // This line throws a compilation error
}

该类及其所有基类(一直到
Object.class
)都提供所有公共函数。这里的键是实例的声明类型。例如:

Base b = new Derived();
b.f(10); // prints Base.f()
b.f("foo"); // does not compile

Derived d = new Derived();
d.f(10); // prints Base.f()
d.f("foo"); // prints derived.f()
即使b的运行时类型是
派生的.class
,声明的类型也是
Base.class
。您可以在接口中看到相同的行为:

List list = new ArrayList();

您只能访问在
列表中声明的方法,而不是所有的
ArrayList
重写方法必须具有相同的参数列表。 如果不是,则函数作为重载函数工作。

在上述情况下,您的基类函数在
d.f(5)上匹配调用。

-简而言之:该函数可用(您对此几乎无能为力)。这并没有明显的误导性。我的两种语言的经验(我也学会C++ C++)是,对于大多数程序员来说,java行为是直观的,C++行为是混淆的。它是如何误导的?code>f(inti)
是继承的,因此当您将
int
传递给
f
时,该变量将被执行。通过
Derived
扩展
Base
您可以通过引用
Derived
Base
调用所有继承的方法。你认为哪个部分是误导的?你不能把这个C++程序翻译成java。Java没有指针。如果你发布了两个等价的程序,那就更有趣了。“C++中,它不搜索基类来调用函数/方法默认”是胡说八道。你能解释一下为什么它是胡说八道吗?