【问题标题】:Acessing grandparent's method in java在java中访问祖父母方法
【发布时间】:2021-01-11 00:52:34
【问题描述】:

我正在使用 java 解决简单的 OOP 概念练习问题 该问题给出了一个uml图并要求实施。 我遇到了一个问题,它要求我从子类访问祖父母类中的方法。

见插图:

    
class Grandparent { 
    public void Print() { 
        System.out.println("Grandparent's Print()"); 
    } 
} 

class Parent extends Grandparent { 
    public void Print() {    
        System.out.println("Parent's Print()"); 
    } 
} 

class Child extends Parent { 
    public void Print() { 
        super.super.Print(); // Trying to access Grandparent's Print() 
        System.out.println("Child's Print()"); 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
        Child c = new Child(); 
        c.Print(); 
    } 
} 
 

我在所有地方都做了我的研究,我发现 java 不允许这样做,因为应用了 Encpculation 但是它在 C++ 中是允许的,我的问题是我可以做些什么来从不允许的祖父类( super. java 中的 super.method() ) 语句。

我的意思是我可以改变结构,保持原有的继承,并且可以在缺少 UML 的情况下访问该方法。

【问题讨论】:

    标签: java oop inheritance encapsulation


    【解决方案1】:

    您可以创建 GrandParent 类的引用变量和 Child 类的对象。于是代码变成了这样:

        class Grandparent { 
        public void Print() { 
            System.out.println("Grandparent's Print()"); 
        } 
    } 
    
    class Parent extends Grandparent { 
        public void Print() {    
            System.out.println("Parent's Print()"); 
        } 
    } 
    
    class Child extends Parent { 
        public void Print() { 
            //super.super.Print(); // Trying to access Grandparent's Print() 
            System.out.println("Child's Print()"); 
        } 
    } 
    
    public class Main { 
        public static void main(String[] args) { 
            GrandParent p = new Child(); 
            p.Print(); 
        } 
    }
    

    这里发生的情况是,使用的引用变量是父类之一,因此即使为子类创建对象,引用变量也只知道类中存在的方法“GrandParent” 并且相同方法的输出会显示在屏幕上。

    这对所有的父类都是允许的,也就是说所有的父类引用变量都可以使用子类的对象来引用,反之则不然。

    【讨论】:

    • 我猜这不会调用祖父类的打印,因为它在堆中是一个子对象,它会去那里然后会调用孩子的打印
    • 它只会调用 GrabndParent 类的方法,但问题是它被子类覆盖。所以它正在打印子类的值。调用它的唯一方法是由每个孩子调用其父母。我提供的代码适用于静态方法。因为静态方法不能被覆盖。它们在子类中创建时被隐藏。
    【解决方案2】:

    我认为你应该像这样编写 Parent 的 print() 方法:

    public void Print() {   
      super.print()
        System.out.println("Parent's Print()"); 
    }
    

    还有孩子的 print() 方法。
    这样做就可以了。

    【讨论】:

      【解决方案3】:
      1. java中没有办法调用super.super.foo()。

      2. 您可以通过以下方式隐式执行:

        public class Grandparent {
            public void Print() { 
                System.out.println("Grandparent's Print()"); 
            } 
        }
        class Parent extends Grandparent { 
            public void Print() { 
                super.Print(); // Here we can add a call to Print() from Grandparent.
                System.out.println("Parent's Print()"); 
            } 
        } 
        
        class Child extends Parent { 
            public void Print() { 
                super.Print(); 
                System.out.println("Child's Print()"); 
            } 
        } 
        
        public class Main { 
            public static void main(String[] args) { 
                Child c = new Child(); 
                c.Print(); 
            } 
        } 
        
      • 注意:尝试对方法使用命名约定。对 Print() 使用 lowerCamelCase -> print()

      【讨论】:

        【解决方案4】:

        您可以使用反射获得预期结果,但为此您需要确切知道超类的级别。

        Child c = new Child();
        Constructor<?> constructor = c.getClass().getSuperclass()
                       .getSuperclass().getDeclaredConstructor();
        constructor.setAccessible(true);
        ((Grandparent)constructor.newInstance()).Print();
        

        【讨论】:

          猜你喜欢
          • 2012-04-26
          • 2011-06-09
          • 1970-01-01
          • 2011-07-11
          • 1970-01-01
          • 2011-02-04
          • 2011-11-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多