java中不同包的受保护成员访问 - 一个好奇

发布于 2024-10-30 15:57:50 字数 482 浏览 5 评论 0原文

package packageOne;
public class Base
{
    protected void display(){
        System.out.println("in Base");
    }
}


package packageTwo;
public class Derived extends packageOne.Base {
    public void show(){
        new Base().display(); //this is not working throws compilation error that display() from the type Base is not visible
        new Derived().display(); //is working
        display(); //is working
    }
}

这两个包位于两个不同的文件中。但为什么会有这种行为呢?

package packageOne;
public class Base
{
    protected void display(){
        System.out.println("in Base");
    }
}


package packageTwo;
public class Derived extends packageOne.Base {
    public void show(){
        new Base().display(); //this is not working throws compilation error that display() from the type Base is not visible
        new Derived().display(); //is working
        display(); //is working
    }
}

The two packages are in two different files. But why this behaviour?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

指尖微凉心微凉 2024-11-06 15:57:51

这可能是对您问题的直接回答,但我认为您没有理由调用 new Base().display();。也许你的意思是 super.display();

在这种情况下,您实际上正在使用继承的方法,但仅仅因为您继承了一个类,并不意味着您可以访问受保护的方法(根据定义,仅对超类可见)。

区别在于,在一种情况(您的示例)中,您尝试从您继承的类的实例访问受保护的方法。在我的示例中,您可以通过继承访问受保护的方法。

总之:您可以通过继承上下文访问该方法。

为什么?

它使程序员可以灵活地决定哪些功能只能由直系后代使用或扩展。

This might be a direct answer to your question, but i see no reason why you would call new Base().display();. Perhaps what you mean in super.display();.

In this case, you are actually using the inherited method, but just because you're inheriting a class, it doesn't mean that you access to the class protected methods (which by definition are only visible to super classes).

The difference is on one case (your example) you're trying to access a protected method from an instance of a class that you inherited. In my example, you can access the protected method through inheritance.

In summary: you can access the method through inheritance context.

Why?

It gives programmers flexibility in deciding which features can only be used or extended by direct descendants.

大姐,你呐 2024-11-06 15:57:51

对象的受保护成员或构造函数可以从包外部访问,在包中只能由负责实现该对象的代码来声明它。

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

忆离笙 2024-11-06 15:57:51

display 不是 Base 内部的静态方法。所以,你必须先创建一个Base实例,然后调用display。

Base base = new Base();
base.display();

display is not a static method inside Base. So, you have to first create an instance of Base and then call display.

Base base = new Base();
base.display();
最丧也最甜 2024-11-06 15:57:50

protected 允许子类同一包中的其他类进行访问。这就是为什么任何 Derived 类实例都可以访问 Base 中受保护的方法。

另一行创建一个 Base 实例(不是 Derived 实例!!)。并且只允许来自同一包的对象访问该实例的受保护方法。


display();

-> 允许,因为调用者,Derived 的实例可以访问其子类的受保护成员和字段,即使它们位于不同的包中

new Derived().display();

-> 允许,因为您在 Derived 实例上调用该方法,并且该实例可以访问其子类的受保护方法

new Base().display();

-> 不允许,因为调用者的(this实例)类没有像Base类一样定义在同一个包中,所以this< /code> 无法访问受保护的方法。正如我们所看到的,当前从该包中继承一个类并不重要。该后门已关闭;)

protected allows access from subclasses and from other classes in the same package. That's why any Derived class instance can access the protected method in Base.

The other line creates a Base instance (not a Derived instance!!). And access to protected methods of that instance is only allowed from objects of the same package.


display();

-> allowed, because the caller, an instance of Derived has access to protected members and fields of its subclasses, even if they're in different packages

new Derived().display();

-> allowed, because you call the method on an instance of Derived and that instance has access to the protected methods of its subclasses

new Base().display();

-> not allowed because the caller's (the this instance) class is not defined in the same package like the Base class, so this can't access the protected method. And it doesn't matter - as we see - that the current subclasses a class from that package. That backdoor is closed ;)

染柒℉ 2024-11-06 15:57:50

http://java.sun.com/docs/books /jls/third_edition/html/names.html#6.6

class C
    protected member;

// in a different package

class S extends C 

    obj.member; // only allowed if type of obj is S or subclass of S

动机大概如下。如果obj是一个S,类S对其内部有足够的了解,它有权操作它的成员,并且它可以做到这一点安全。

如果 obj 不是 S,它可能是 C 的另一个子类 S2,其中 S代码> 不知道。当S被写入时,S2可能还没有诞生。对于 S 来说,操纵 S2 受保护的内部结构是相当危险的。如果允许这样做,从 S2 的角度来看,它不知道谁会篡改其受保护的内部结构以及如何篡改,这使得 S2 工作很难推理关于它自己的状态。

现在,如果objD,并且D扩展了S,那么S访问obj是否危险? .member?并不真地。 S 如何使用 memberS 及其所有子类(包括 D)的共享知识。 S作为超类有定义行为的权利,而D作为子类有接受和遵守的义务。

为了更容易理解,规则实际上应该简化为要求 obj 的(静态)类型完全是 S。毕竟,子类D出现在S中是非常不寻常和不合适的。即使发生这种情况,obj 的静态类型是 D,我们的简化规则也可以通过向上转换轻松处理它:((S)obj)。会员

http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.6

class C
    protected member;

// in a different package

class S extends C 

    obj.member; // only allowed if type of obj is S or subclass of S

The motivation is probably as following. If obj is an S, class S has sufficient knowlege of its internals, it has the right to manipulate its members, and it can do this safely.

If obj is not an S, it's probably another subclass S2 of C, which S has no idea of. S2 may have not even been born when S is written. For S to manipulate S2's protected internals is quite dangerous. If this is allowed, from S2's point of view, it doesn't know who will tamper with its protected internals and how, this makes S2 job very hard to reason about its own state.

Now if obj is D, and D extends S, is it dangerous for S to access obj.member? Not really. How S uses member is a shared knowlege of S and all its subclasses, including D. S as the superclass has the right to define behaviors, and D as the subclass has the obligation to accept and conform.

For easier understanding, the rule should really be simplified to require obj's (static) type to be exactly S. After all, it's very unusual and inappropriate for subclass D to appear in S. And even if it happens, that the static type of obj is D, our simplified rule can deal with it easily by upcasting: ((S)obj).member

暗藏城府 2024-11-06 15:57:50

受保护的访问有一些特殊规则,详细信息请参见 Java语言规范

对象的受保护成员或构造函数可以从包外部访问,在该包中,它只能由负责实现该对象的代码声明。

Protected access has some special rules that are detailed in the Java Language Specification:

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

眼眸 2024-11-06 15:57:50

首先想到的是,您可以在任何软件中使用 protected Object,但只有不同的包非子类不能从其他类访问受保护的成员。这意味着你不能直接使用它。首先你得到那个 obj 然后使用。

    package Demos;

    public class AB
    {
        public    int a = 14;
        protected int b = 13;   
    }

我们还有另一个类,就像

package Example;

import Demos.AB;

public class Ex1 extends AB
{
    public static void main(String[] args)
    {
        AB obj = new AB();          // obj of AB                OR
                                    // AB obj = new Ex1(); object of Ex1 but referance of AB
                                    // cant use protacted member

        System.out.println(obj.a);
        System.out.println(obj.b);  //You can't use 


        Ex1 obj1 = new Ex1();       // you have to make obj of sub-class referance of Ex1
        System.out.println(obj1.a);
        System.out.println(obj1.b);  // Now You can use
    }
}

在这件事上你必须扩展受保护成员的类,然后使用你不能直接使用的。

First think is that you can use protected Object in any ware, but only Different package non-subclass cant access protected member from other class. it means you cant use it directly. first you get that obj and then use.

    package Demos;

    public class AB
    {
        public    int a = 14;
        protected int b = 13;   
    }

and we have another class like

package Example;

import Demos.AB;

public class Ex1 extends AB
{
    public static void main(String[] args)
    {
        AB obj = new AB();          // obj of AB                OR
                                    // AB obj = new Ex1(); object of Ex1 but referance of AB
                                    // cant use protacted member

        System.out.println(obj.a);
        System.out.println(obj.b);  //You can't use 


        Ex1 obj1 = new Ex1();       // you have to make obj of sub-class referance of Ex1
        System.out.println(obj1.a);
        System.out.println(obj1.b);  // Now You can use
    }
}

in this matter you have to extends class of protected member and then use you cant use is directly.

悲喜皆因你 2024-11-06 15:57:50
new Base().display();

它创建一个 Base 对象,然后尝试在其上调用 display()。
显然它不起作用,因为 Base 上的 display() 受到保护。

new Base().display();

It creates a Base object, and then trys to call the display() on it.
Obviously it won't work, because the display() on Base is protected.

过气美图社 2024-11-06 15:57:50

这是预期的行为。 protected 表示继承类和同包类都可以看到该方法。所以,这就是你所看到的。

This is the intended behaviour. protected means that the inherited classes and same package classes can see the method. So, it's what you see.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文