覆盖匿名类中的方法

时间:2013-04-26 11:20:29

标签: java

我有两节课。 Parent和Child.In在Child类中,我使用匿名Inner类来覆盖Parent类方法。如果我在Child的匿名类(Parent Class)中添加任何方法,我应该在实际的Parent类中定义相同的方法吗?

  1. 我可以在匿名类中拥有自己的新方法定义。
  2. 为什么Anonymous类中的Methods应该已经在实际的Parent类中定义
  3. 代码:

    public class Parent 
    {
        public static void main(String[] args) 
        {
            new Child().CallMe();
        }       
    }
    
    class Child
    {
        Parent objParent = new Parent()
        {
            void displayMsg()
            {
                System.out.println("Display Msg for Child");
            }
        };
    
        void CallMe()
        {
            objParent.displayMsg();
        }
    }
    

    因此,在上面的示例中,如果您在Parent或Child中删除displayMsg(),则会显示错误。

4 个答案:

答案 0 :(得分:3)

  
      
  1. 我可以在匿名类中拥有自己的新方法定义。
  2.   

您可以定义新方法,但只能通过anyonmous类的其他方法访问它们。

  

2.为什么Anonymous类中的Methods应该已经定义了   实际的父类

您正在创建的对象的类型为“Parent”。因此,它仅公开“父”对象提供的方法。

要理解的一个例子是,如果将任何对象转换为“Object”,新引用将只显示“Object”方法。

Object object = (Object)whateverObject;

答案 1 :(得分:3)

通过

Parent objParent = new Parent()
    {
        void displayMsg()
        {
            System.out.println("Display Msg for Child");
        }
    };

您只是覆盖了Parent类的方法displayMsg()objParent是一个内联类(扩展Parent),您可以在其中拥有自己的方法,如下所示(回答1)

class Child
{
    Parent objParent = new Parent()
    {
        void displayMsg()
        {
            System.out.println("Display Msg for Parent");
        }

        void someMethod() {

        }
    };

    void CallMe()
    {
        objParent.displayMsg();
    }
}

你甚至可以避免重写,但仍然定义你的新方法如下(答案2)

class Child
{
    Parent objParent = new Parent()
    {
        void someMethod() {

        }
    };

    void CallMe()
    {
        objParent.displayMsg();
    }
}

答案 2 :(得分:2)

如果您从displayMsg移除Parent,则Child.CallMe()将失败,因为Parent没有定义displayMsg。只是在匿名类中实现它不会在Parent类上公开该方法。匿名实现将是一个子类。但是,由于您将变量分配给Parent类型(而不是实际的子类,这可能是不可能的),因此无法解析此方法。

可以在匿名类中添加其他方法,但只能从匿名类中看到它们(除非你决定反思)。

displayMsg中的匿名类中删除Child但是,就我所见,不应该产生错误。但话说回来,你只是在实例化父母......

修改

但是,我确实怀疑你所寻找的是简单的继承:

public class Child extends Parent {

    @Override
    void displayMsg() {
        // Child specific displayMsg
    }
}

在这种情况下,Parent中不需要内部Child实例,因为Child也是Parent的实例,并且继承了它的行为。

修改2

回应你自己的答案。假设我们有一个Person类:

public class Person {
    private String name;
    private int age;

    public String sayHello() {
        return "Hi there, my name is " + name + ", and I'm " + age " years old";
    }
}

我们假设我们有一个Employee的课程Person

public class Employee extends Person {
    public String company;
    public double salary;

    @Override
    public String sayHello() {
        return super.sayHello() + ". I work at " + company + " and my salary is " + salary;
    }

    public void goToWork() {
        // Go do some work!
    }
}

现在,请考虑一下:

Person p = new Employee();
p.goToWork(); // Will not work, as the method is declared in the subclass, not in Person

因此,如果我想将员工视为员工,我需要做

Employee e = new Employee();
e.goToWork();

但是,在这两种情况下,我都可以将它们视为Person

Person p = new Employee();
// This works, as it's defined in Person. It will also invoke the actual sayHello
// in the Employee class
String hi = p.sayHello(); 

goToWork添加到Person类是没有意义的,只是因为你想调用它声明为Person。让我们看看如果我们这样做会带来什么影响。

public class Student extends Person {

     private String school;

     @Override
     public String sayHello() {
         return super.sayHello() + ". I'm studying at " + school;
     }

     public void goToSchool() {
     }

}

现在,学生将同时拥有goToWorkgoToSchool(当然,有些学生也在公司工作,但是我们不要再深入研究多重继承......)。我不会将goToSchool移到Person班级。同样,如果我想将此Student视为Student,我需要将其声明为Student

Student s = new Student();
s.goToSchool();

如果我要将所有这些方法移到Person班级,Person将有两种与上学和上班相关的方法,无论Person是什么类型。并非所有Person人(人)都去上学,而不是所有人都去上班。

答案 3 :(得分:0)

感谢所有回复的人。我现在有了概念。

在内联类中我正在使用父引用。它与下面的类似。

Parent p = new Child()

因此,为了使用Parent引用访问子进程中的方法,子类应该重新定义Parent中定义的所有方法。

同样的事情发生在我正在使用父引用的匿名内部类中。因此,每当我在Inline类中添加一个新方法时,我应该在Parent类中定义相同的方法。否则它将生成一个错误。