在 java 中访问祖父母方法

Acessing grandparent's method in java

我正在使用 java 练习简单的 OOP 概念 题目给了一个uml图,要求实现。 我遇到了一个问题,它要求我从 child class.

访问祖父母 class 中的一个方法

见插图:

    
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++ 中是允许的,我的问题是我可以做些什么来从祖父母那里得到那个方法 class 在 java 中不允许的 ( super.super.method() ) 语句旁边。

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

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

    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(); 
    } 
}

这里发生的事情是,使用的引用变量是父对象之一 class 所以即使对象是为子对象创建的 class 引用变量只知道存在的方法在 class "GrandParent" 中,相同方法的输出显示在屏幕上。

这对于所有父classes是允许的,也就是说所有父class引用变量都可以使用子class的对象来引用,但是副反之亦然。

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

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

还有 child 的 print() 方法。
通过这样做它会起作用。

  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() -> print()
  • 使用 lowerCamelCase

你可以使用反射得到预期的结果,但是为此你需要确切地知道超级 class 有多少层。

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