`

protected子类可见为什么在子类中调用有时会编译出错?

阅读更多
package family;
        
public class Student {
        
    protected void tt(){
        System.out.println("I am a student...");
    }    
}

///调用类
package temp;

public class Doctor extends family.Student{
    
    void ss(){
        new family.Student().tt(); // compile-time error    
    }
}

 我觉得这个问题其实挺典型的,问题出在“protected子类可见”这种介绍比较笼统吧

 

 


The fields x and y are declared protected and are accessible outside the package points only in subclasses of class Point, and only when they are fields of objects that are being implemented by the code that is accessing them.

在包外访问proteced成员只有在其声明类的子孙类中且只有当它们是访问它们的代码所实现的对象的成员时

比如
package temp;

public class Doctor extends family.Student{
   
    void ss(){
        new family.Student().tt();
    }
}

这里虽然是在子类中,但非访问它们的代码所实现的对象,应该是Doctor,而非Student

 

package temp;

public class Doctor extends family.Student{
   
    void ss(){
        new family.Doctor().tt();
    }
}

至于为什么是这样?我想初步的可能就是为了防止使用Student的客户直接访问吧,是直接访问,
尽可能地防止误用而产生的错误,就需要用到这些

 

Consider this example, where the points package declares:

 

package points;
public class Point {
        protected int x, y;
        void warp(threePoint.Point3d a) {
                if (a.z > 0)         // compile-time error: cannot access a.z
                        a.delta(this);
        }
}

and the threePoint package declares:

 

package threePoint;
import points.Point;
public class Point3d extends Point {
        protected int z;
        public void delta(Point p) {
                p.x += this.x;          // compile-time error: cannot access p.x
                p.y += this.y;          // compile-time error: cannot access p.y

        }
        public void delta3d(Point3d q) {
                q.x += this.x;
                q.y += this.y;
                q.z += this.z;
        }
}

which defines a class Point3d . A compile-time error occurs in the method delta here: it cannot access the protected members x and y of its parameter p , because while Point3d (the class in which the references to fields x and y occur) is a subclass of Point (the class in which x and y are declared), it is not involved in the implementation of a Point (the type of the parameter p ). The method delta3d can access the protected members of its parameter q , because the class Point3d is a subclass of Point and is involved in the implementation of a Point3d .

The method delta could try to cast (§5.5 , §15.16 ) its parameter to be a Point3d , but this cast would fail, causing an exception, if the class of p at run time were not Point3d .

A compile-time error also occurs in the method warp: it cannot access the protected member z of its parameter a , because while the class Point (the class in which the reference to field z occurs) is involved in the implementation of a Point3d (the type of the parameter a ), it is not a subclass of Point3d (the class in which z is declared).

 

附参考资料:

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

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

 

分享到:
评论

相关推荐

    论JAVA继承机制中父类与子类的关系

    这意味着在子类中调用该方法时,会执行子类的方法体。 ##### 3. 如何避免覆盖或重写? 如果在某些情况下,开发者不希望子类覆盖或重写父类的方法或成员变量,可以利用`super`关键字来显式地访问父类中的成员。例如...

    父类引用指向子类对象

    访问权限方面,`public`属性和方法在任何情况下都可以被访问,`protected`成员在同包内和子类中可以访问,`default`(包访问权限)仅在同包内可访问,而`private`成员只在其定义的类内部可见。因此,如果父类引用...

    将子类引用赋给父类对象时,java虚拟主机并没有将那些非继承成员丢弃

    然而,这并不意味着在转换过程中会丢失子类的非继承成员,即那些在父类中不存在的方法或属性。Java虚拟机(JVM)在内存中以特定方式存储这些成员,使得它们在需要时依然可以访问。 首先,理解Java中的类继承关系。...

    C++第一个调用项目

    在C++编程中,"第一个调用项目"通常是指创建一个简单的程序,演示如何在不同类之间进行方法调用,这是学习面向对象编程的基础。在这个项目中,我们将在C++的基础环境中建立这样的调用关系,初步搭建C++的编码环境。 ...

    Java继承习题

    子类可以在自己的构造函数中使用`super`关键字来调用父类的含参数构造函数,但这个调用语句必须是子类构造函数的第一个可执行语句 - C. 在创建子类的对象时,将先执行继承自父类的无参构造函数,然后再执行自己的...

    Java语言程序设计基础第十版第十一章课后复习题答案

    - **题目**: 下面的说法是真是假:当从子类调用构造方法时,它的父类的无参构造方法总是会被调用? - **答案**: 假,如果通过参数调用呢 - **解析**: 如果子类的构造函数中没有显式调用父类的构造函数,则默认会调用...

    Java面试题及答案.pdf

    因此,C选项是正确的,程序在编译时会出错,不会输出任何结果。 这些面试问题涵盖了Java的关键概念,包括继承、多态、方法重写、访问修饰符以及静态与实例方法的区别。理解和掌握这些知识点对于Java开发者来说至关...

    面向对象oop详解

    向上转型是将子类对象赋值给父类引用的过程,是一种自动类型转换,此时可以调用父类中的方法,如果方法在子类中被重写了,那么会调用子类中的实现,这种机制被称为动态绑定。多态的实现减少了代码的冗余,提高了程序...

    非自动继承的函数

    1. **私有(private)成员函数**:私有成员函数在基类中是不可见的,因此子类无法直接访问。为了在子类中使用这些函数,需要通过公有或保护的接口进行间接调用,或者使用友元(friend)机制。 2. **虚函数(virtual...

    JAVA面向对象编程继承性和多态性PPT教案学习.pptx

    构造方法调用的规定要求子类构造器必须在第一行调用父类的构造器,如果没有显式调用,系统会自动调用父类无参数构造器,除非父类没有这样的构造器。 `protected`和`final`关键字在继承中也有特定用途。`protected`...

    类的继承练习_inheritance_类的继承练习_C++_pineoce_

    - `protected`继承:与`private`继承类似,但父类的保护成员在子类中仍保持为保护成员。 3. **虚函数与多态**:为了实现运行时的多态性,C++引入了虚函数(`virtual`关键字)。在基类中声明虚函数,子类可以覆盖...

    Java面试题(卷)与答案解析.doc

    - 题目中,`Child`类试图通过实例方法`test()`重写`Base`类的静态方法`test()`,这在编译时就会出错,因为Java不允许这种情况。 5. **访问控制与方法调用**: - `private`方法只能在定义它的类内部被调用,因此`...

    java考试题汇总java考试题汇总.doc

    在Java中,内部类默认是包私有的,除非明确声明为`protected`或`public`。因此,试图从外部类继承一个私有内部类会导致编译错误。正确答案是b) `一个Test.java文件中不能声明两个类`,尽管这不是导致错误的原因,但...

    JAVA面向对象JAVA面向对象.doc

    - `protected` 修饰的成员(如 `z`),可以在同一个包内的任何类中访问,也可以在不同包中 `A` 的子类中访问。这提供了一种保护机制,允许子类访问一些需要控制的成员,但限制了外部类的访问。 5. **方法的可见性*...

    C++ 新建类函数及调用

    在本教程中,我们将深入探讨如何在Visual Studio 2008环境下创建和使用C++类,以及如何调用类中的成员函数。 首先,让我们了解什么是类。类是对象的蓝图,定义了一组属性(数据成员)和行为(成员函数)。在C++中,...

    java的继承.docx

    同样,当子类重写父类的方法时,如果需要在子类中调用父类的被覆盖方法,也可以使用 `super.method()`。 方法的重写是继承的一个重要方面,它允许子类根据自身需求定制父类的行为。重写的方法必须有与父类完全相同...

    java 面试题整理

    `private`仅在类内部可见,`public`对所有地方都可见,`protected`在同一个包或子类中可见,而默认(package-private)则在同包内可见。 3. **类与对象的区别**:类是对象的模板,它定义了对象的属性和行为;对象是...

    Java面向对象的学习(关键字)

    `this`修饰的变量在当前类找不到时,会继续在父类中查找,而`super`修饰的变量仅限于父类中寻找,若在父类中不存在而子类中有,则会引发编译错误。在成员方法调用上,`this`和`super`的行为类似,但在构造方法中,...

    第十一节 方法覆盖.docx

    在这种情况下,即使父类引用只能调用父类中定义的方法,但如果这些方法在子类中被覆盖,那么实际执行的是子类的方法。这种现象称为动态绑定或晚期绑定。 例如,在约瑟夫问题的示例中,`Demo4`类创建了一个`Cyclink`...

    SATC答案3教案资料.pdf

    - C选项描述了`protected`修饰的属性和方法在子类中被继承且可访问,这是正确的,`protected`成员在子类中是可见的。 - D选项提到,父类中默认(即包私有)修饰的属性和方法在子类中被继承,如果它们在同一个包中...

Global site tag (gtag.js) - Google Analytics