一直记得java类中用protected修饰的成员是可以让子类访问的,但一直没实际去操作一下。今天发现原来虽然子类可以访问父类的protected成员,但还是不能用在子类中实例化一个父类对象的方式去访问protected成员,需要使用this.x或this.x()的形式或者实例化子类去访问(x代表成员变量或方法)

 

然而,静态的用protected修饰的成员变量或成员方法又可以直接用类名.x或者类名.x()或者实例化的父类对象去访问。

 

今天做Thinking in java的习题的时候又碰到了一个关于protected类型的内部类的问题,在这里一起记录一下。

题目是第9章 inner class 的Exercise 6。要求在第一个包里创建一个interface,里面至少包含一个方法。在第二个包里创建一个类,这个类需要包含一个protected类型的内部类,并且这个内部类要实现在第一个包里创建的接口。在第三个包里要创建一个类,继承第二个包里的那个类,并且写一个方法创建一个第二个包里的内部类的对象,将这个对象向上转型成第一个包里的接口并返回。以下是我写的代码:

一:接口Input,代表  输入设备

1 package innerclass.exercise6;
2 
3 public interface Input {
4     void inputInstruction(String s);
5 }

二:类Computer,里面有一个protected修饰的Mouse内部类(代表鼠标),并且Mouse实现Inout接口

package innerclass.exercise6.other;

import innerclass.exercise6.Input;

public class Computer {
    protected int i = 2;
    protected class Mouse implements Input {
        @Override
        public void inputInstruction(String s) {
            System.out.println("execute "+s);
        }
    }
}

 

 三:类Lenovo,继承Computer类,在getComputetMouse()方法里试图创建一个Computer.Mouse对象,并向上转型为Input并返回。

package innerclass.exercise6.another;

import innerclass.exercise6.Input;
import innerclass.exercise6.other.Computer;

public class Lenovo extends Computer {

    Input getComputerMouse() {
        this.i++;
        Input computerMouse = this.new Mouse();
        return computerMouse;
    }

    public static void main(String[] args) {
        Lenovo lenovo = new Lenovo();
        lenovo.getComputerMouse().inputInstruction("open fire");
    }
}

本以为没啥问题,但
Input computerMouse = this.new Mouse();

 

这一行却飘红了,idea提示“'innerclass.exercise6.other.Computer.Mouse' has protected access in 'innerclass.exercise6.other.Computer'”
这我就很疑惑了,Lenovo作为Computer的子类,也能够正常访问同样是protected类型的成员变量i,甚至我可以单单声明一个Mouse类型的变量(但不实例化),为啥一
调用Mouse的构造方法就报错呢?
后来看了别人的答案才发现,给Mouse加一个public的构造方法就可以了。原来,类的构造方法的访问权限默认是和类的访问权限一致的,由于Mouse是protected的访问
权限,它的默认构造函数也就是protected的访问权限,而Lenovo和Mouse既不处于同一个包中,又不是Mouse的子类,自然是无法访问Mouse的protected权限的构造方
法的。所以要想在Lenovo中得到一个Mouse的对象,就需要自己给Mouse加一个public访问权限的构造方法。
至于可以在Lenovo里单单声明一个Mouse类型的变量,我认为是可以把Mouse和i一样看作是Computer的成员变量,Lenovo作为Computer的子类,自然可以访问到Computer
的protected权限的成员变量Mouse。(当然,这只是我自己这样理解的,内部类跟成员变量应该还是有不同的吧)

另有一个知识点提一下,只有内部类才能用private或者protect去修饰,一般的类是只有public或者package(默认)访问权限的。

版权声明:本文为youngerjoel原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/youngerjoel/p/12912870.html