1

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

  1. 我可以在匿名类中有自己的新方法定义吗?
  2. 为什么匿名类中的方法应该已经在实际的父类中定义

代码:

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

所以在上面的例子中,如果你displayMsg()在 Parent 或 Child 中删除它会显示错误。

4

5 回答 5

3
  1. 我可以在匿名类中有自己的新方法定义吗?

您可以定义新方法,但它们只能由任意类的其他方法访问。

2.为什么匿名类中的方法应该已经在实际的父类中定义了

您正在创建的对象是“父”类型。因此它只公开“父”对象提供的方法。

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

Object object = (Object)whateverObject;
于 2013-04-26T11:27:33.107 回答
3

通过做

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

你只是覆盖了Parent类的方法displayMsg()objParent是一个内联类(extends 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();
    }
}
于 2013-04-26T11:29:14.677 回答
2

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

可以向匿名类添加其他方法,但它们只能在匿名类中可见(除非您解析为反射)。

displayMsg然而,据我所知,从匿名类中删除不Child应该产生错误。但是话又说回来,你只是在实例化一个 Parent ......

编辑

但是,我确实怀疑您正在寻找的是简单的继承:

public class Child extends Parent {

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

在这种情况下,不需要 in 的内部Parent实例Child,因为Childalso 是 , 的实例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视为 a Student,我需要将其声明为 a Student

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

如果我把所有这些方法都搬到Person课堂Person上,无论是什么类型的Person. 不是所有Person的人(人)都去上学,也不是所有的人都去工作。

于 2013-04-26T11:27:22.483 回答
0

感谢所有回复的人。我现在得到了这个概念。

在内联类中,我正在使用父引用。它就像下面的那个。

Parent p = new Child()

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

同样的事情发生在我使用父引用的匿名内部类中。所以每当我在内联类中添加一个新方法时,我应该在父类中定义相同的方法。否则它会产生一个错误。

于 2013-04-26T12:09:39.800 回答
0

从一个类创建匿名类时,会扩展该类。匿名类的最初目的是提供用于创建它的类/接口的覆盖实现。

在您的情况下,Parent该类是匿名类的超类。作为超类引用,Parent可以保存单个匿名子类对象,但只能Parent通过引用访问类中定义的方法。

想象它只是扩展Parent类,而不是重新定义Parent类。

匿名类不能被实例化为它们自己的独立实体。它们作为类/接口的扩展/实现存在。

objParent.displayMsg();

这里,objParent是类 Parent 的引用,而不是匿名类的引用。

尽管匿名类可以有自己的方法声明,但它们不能通过引用访问,因为我们无法创建匿名类的纯引用。我们总是需要超类/接口引用来保存匿名类对象。

于 2021-09-06T02:53:42.850 回答