来自其他包的受保护方法调用

时间:2014-09-13 07:58:35

标签: java protected modifier

我以为我理解protected修饰符,但看起来我没有。 这个例子很简单:

package com;
public class Main {

     protected void method1() {
         // some code
     }
}

package net;

import com.Main;

public class Out extends Main {

    public Out(){
         Main m = new Main();
         m.method1();
    }
}

为什么我不能从扩展method1的类中调用Main?编译器错误建议将修饰符更改为public

我真的很困惑。

3 个答案:

答案 0 :(得分:0)

它不起作用,因为您在Main中创建了Out个实例(OutMain,但Main不是{ {1}})。

如果您直接致电Out

,它会有效
method1

或者如果您有public Out(){ method1(); } 个实例:

Out

public Out(){
    Main m = new Main();
    ((Out)m).method1();
}

Here您可以找到一些细节(第6.6.2节):

  

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

答案 1 :(得分:0)

package com.example.furniture;

public class Seat {

    public boolean canAccommodate(int numberOfPeople) {
        return numberOfPeople <= getMaxNumberOfPeopleThatICanAccommodate();
    }

    protected int getMaxNumberOfPeopleThatICanAccommodate() {
        return 4;
    }

}


package com.example.furniture;

public class Chair extends Seat {

    public boolean willBreakIfNumberOfPeopleSittingExceeds(int numberOfPeople) {
        return numberOfPeople > getMaxNumberOfPeopleThatICanAccommodate();
    }

}

即使在getMaxNumberOfPeopleThatICanAccommodate()中未明确定义Chair,上述内容仍然有效,Chair将使用Seat中的实现。 protected修饰符允许子类调用(或覆盖)该方法,并允许来自同一个包的类调用该方法:

package com.example.furniture;

public class Bed {

    public boolean canFitMorePeopleThanThis(Seat seat) {
        return peopleICanFit() > seat.getMaxNumberOfPeopleThatICanAccommodate();
    }

    private int peopleICanFit() {
        return 2;
    }

}

使用受保护方法扩展一个类的类也可以覆盖该方法:

package com.example.furniture;

public class ReallySmallChair extends Seat {

    public boolean willBreakIfNumberOfPeopleSittingExceeds(int numberOfPeople) {
        return numberOfPeople > getMaxNumberOfPeopleThatICanAccommodate();
    }

    @Override
    protected int getMaxNumberOfPeopleThatICanAccommodate() {
        return 1;
    }

}

但是如果您尝试从外部程序包访问受保护的方法,它将无法正常工作:

package com.example.room;

public class LivingRoom {

    Seat seat = new Seat();
    Seat chair = new Chair();

    public boolean canAccommodate(int numberOfPeople) {
        int maxAccommodate = seat.getMaxNumberOfPeopleThatICanAccommodate() +
                chair.getMaxNumberOfPeopleThatICanAccommodate();

        return numberOfPeople <= maxAccommodate;
    }

}

尝试访问seat.get...chair.get...方法时,您会收到编译错误。

如果您在另一个包中有Seat的子类,那么您仍然可以访问受保护的方法,因为它满足两个条件之一(子类或同一个包中的另一个类),但只有它自己的方法:

package com.example.room;

public class RecreationalVehicle extends Seat {

    public boolean canAccommodate(int numberOfPeople) {
        return numberOfPeople <= getMaxNumberOfPeopleThatICanAccommodate();            
    }

}

这很有效,因为getMaxNumberOfPeopleThatICanAccommodate()是一个属于的方法RecreationalVehicle(它是一个子类)。如果它试图从Seat变量访问它,它将不允许它,因为RecreationalVehicle不允许触及另一个实例的受保护方法,因为它不在同一个包中:

package com.example.room;

public class RecreationalVehicle extends Seat {

    Seat seat = new Seat();

    public void foo() {
        seat.getMaxNumberOfPeopleThatICanAccommodate();            
    }

}

会导致编译错误。

答案 2 :(得分:0)

看起来你实际上可以从不同的包中调用超类的方法,你只是不能明确地做:

package com.example.room;

import com.example.furniture.Seat;

public class RecreationalVehicle extends Seat{

RecreationalVehicle rec = new RecreationalVehicle();

public boolean canAccomodate(int numberOfPeople){

    int n = rec.getMaxNumber();

    getMaxNumber();
    return true;
    }
}

这个类不实现getMaxNumber(),但调用rec.getMaxNumber()是正常的。 那是对超类的实际调用,对吧?

关键是:为什么我们不能从其他包中调用超类的方法 在具有“父”引用类型的对象上?