在类的构造函数上使用受保护的访问修饰符

Posted

技术标签:

【中文标题】在类的构造函数上使用受保护的访问修饰符【英文标题】:Protected access modifier use on Class's Constructor 【发布时间】:2015-10-14 07:07:26 【问题描述】:

我很清楚在公共类的构造函数上使用私有、默认和公共访问修饰符。

如果构造函数是私有的,则只能在该类中创建类对象。

如果构造函数是默认的,则只能在该包的类中创建类对象。

如果构造函数是公共的,则可以在任何类中创建类对象。

我不清楚受保护的构造函数。示例:

默认构造函数

package com.test;
public class PracticeParent 
    PracticeParent()       //Constructor with default access modifier
        System.out.println("PracticeParent default constructor");
    


package com.moreTest;
import com.test.PracticeParent;
public class Test extends PracticeParent   //Error. Implicit super constructor PracticeParent() is not visible for default constructor. Must define an explicit constructor
    public static void main(String[] args) 
        PracticeParent pp=new PracticeParent();     //Error. The constructor PracticeParent() is not visible
    

我理解这些错误。由于 ParentPractice 类在其他包中并且其构造函数是默认的,因此对于隐式调用 super() 的 Test 类默认构造函数是不可见的。此外,由于构造函数不可见,无法创建其对象。

受保护的构造函数

但是随着类 Test 扩展 ParentPractice 和 ParentPractice 具有受保护的构造函数,没有第一个错误,即从 Test 的默认构造函数隐式调用 super() 时出错。隐式超级构造函数 PracticeParent() 对 Test 的默认构造函数可见,但无法创建 PracticeParent 对象。错误显示构造函数 PracticeParent() 不可见。

package com.test;
public class PracticeParent 
    protected PracticeParent()     //Constructor with protected access modifier
        System.out.println("PracticeParent default constructor");
    


package com.moreTest;
import com.test.PracticeParent;
public class Test extends PracticeParent   //No Error
    public static void main(String[] args) 
        PracticeParent pp=new PracticeParent();     //Error. The constructor PracticeParent() is not visible
            /*Test t=new Test();     outputs "PracticeParent default constructor"*/
    

为什么调用了super()却无法创建新的PracticeParent对象?

【问题讨论】:

【参考方案1】:
public class Test extends PracticeParent   //No Error
        public static void main(String[] args) 
            PracticeParent pp=new PracticeParent();     //Error. The constructor PracticeParent() is not visible
            Test t=new Test();     //outputs "PracticeParent default constructor"
        
    

您在这里所做的是让Test 扩展PracticeParent,这意味着Test 本身可以使用受保护的构造函数,因为它继承了它。

PracticeParent pp=new PracticeParent();     //Error. The constructor 

这只是一个常规的实例化,仍然使用或尝试使用不存在的公共构造函数。它将产生与您在应用程序中的任何其他位置调用它时相同的效果/结果。

【讨论】:

表示子类只能使用其继承的父类的受保护属性。该子类之外的任何类都不能使用这些继承的属性。对吗? @Ashish protected 仅表示类本身,从它继承的类可以使用该方法或属性。 由包外的子类扩展的超类的受保护属性对该子类隐含。就好像子类有自己的私有属性,除了那个子类,没有其他类可以访问这些属性。 @Ashish 这是一个陈述还是一个问题? 两者都可以考虑。讨论。

以上是关于在类的构造函数上使用受保护的访问修饰符的主要内容,如果未能解决你的问题,请参考以下文章

PHP中有三种访问修饰符 默认是public

php面向对象-修饰符和抽象类和接口

类的高级概念

Java中受保护的访问修饰符

类的构造方法和析构方法和封装的目的和封装的做法+访问修饰符

类的高级概念