JAVA中动态实例化的优势 [英] Dynamic instantiation advantages in JAVA

查看:181
本文介绍了JAVA中动态实例化的优势的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2节课.动物和马.动物是超一流,马是动物的延伸.

I have 2 classes. Animal and Horse. Animal is the super class, horse extends animal.

public class Animal 
{
    public void legs()
    {
        System.out.println(this + " Some animals can have 3 legs, some have 4");
    }
}

public class Horse extends Animal
{
    public void legs()
    {
        System.out.println(this + " Horses always have 4 legs");
    }

    public void tail()
    {
        System.out.println("A horse definitely has a tail");
    }
}

在另一个类中,我正在这些类上执行一些功能.

From another class, I am doing some functions on these classes.

public class SCJP_Practice
{
    public static void main (String args[])
    {
        Animal a = new Animal();
        Horse h = new Horse();

        a.legs();
        h.legs();

        Animal aa = new Horse();
        aa.legs(); // THIS PRINTS THE HORSE VERSION OF LEGS() AND RIGHTLY SO
        aa.tail(); // THIS IS THROWING A COMPILATION ERROR

    }
}

从理论上讲,aa.tail()虽然可以编译,但仍然是动物类型,这就是为什么它抛出错误的原因,因为它看不到该方法.但是,在运行时,它被实例化为一匹马,并且应该具有利用Horse方法的能力.

Theoretically, aa.tail(), while it compiles is still an Animal type, which is why it throws an error, since it can't see the method. But, during run time, it is instantiated as a horse, and it should have the ability to take advantage of the horse method.

如果没有,那么声明

Animal aa = new Horse();

这样做的好处是什么?

推荐答案

对于类或子类而言,声明Animal aa = new Horse();不仅仅存在.它也存在于接口中:

The declaration Animal aa = new Horse(); doesn't just exist for classes or subclasses; it also exists for interfaces, too:

List<Animal> animalPen = new LinkedList<>();

使用语法的优势取决于您的左手类.

The advantages of using the syntax depend on what your left-hand class are.

如果您使用的是纯继承,则只要在父类中定义了方法,并且将父类视为引用(在本例中为Animal),那么您将受益于虚拟方法调用,Java将使用正确的方法分配给参考的正确实例.

If you're using pure inheritance, then so long as the method is defined in the parent class, and the parent class is treated as the reference (in this case, it'd be Animal), then you would benefit from virtual method invocation, and Java would use the right method for the right instance assigned to the reference.

如果您有不同类型的动物,并且Animal类具有tail方法,而所有其他这些类都覆盖了tail,则将使用子类的tail方法代替父类课.

If you had different types of animals, and the Animal class had a tail method, and all of those other classes override tail, then the subclasses' tail method would be used instead of the parent class.

如果LHS上有一个接口,则说明您遵守该接口的编译时约定.您要说明的是,只要使用了什么实现都符合我关心的接口,实现特定的部分就没有那么重要了.

If you've got an interface on the LHS, then you're conforming to the interface's compile-time contract. You're stating that, so long as whatever implementation is used conforms to the interface I care about, the implementation-specific portions aren't as crucial.

JLS正式规定了规则,

Formally, the rules are spelled out in the JLS, section 15.12.2.1:

由编译时步骤1(第15.12.1节)确定的类或接口是 搜索可能适用于所有成员方法 此方法调用;从超类继承的成员,以及 超级接口包含在此搜索中.

The class or interface determined by compile-time step 1 (§15.12.1) is searched for all member methods that are potentially applicable to this method invocation; members inherited from superclasses and superinterfaces are included in this search.

此外,如果有方法调用,请在左侧之前 括号,形式为Identifier的MethodName,然后进行搜索 流程还会检查(a)导入的所有成员方法 单静态导入声明(第7.5.3节)和按需静态导入 编译单元(§7.3)中的声明(§7.5.4),其中 方法调用发生了,并且(b)在该调用处没有被遮盖(第6.4.1节) 方法调用出现的位置,以确定它们是否为 可能适用.

In addition, if the method invocation has, before the left parenthesis, a MethodName of the form Identifier, then the search process also examines all member methods that are (a) imported by single-static-import declarations (§7.5.3) and static-import-on-demand declarations (§7.5.4) within the compilation unit (§7.3) within which the method invocation occurs, and (b) not shadowed (§6.4.1) at the place where the method invocation appears, to determine if they are potentially applicable.

成员方法可能可能适用 并且仅在以下所有条件都成立的情况下:

A member method is potentially applicable to a method invocation if and only if all of the following are true:

  • 成员的名称与方法调用中的方法的名称相同.

  • The name of the member is identical to the name of the method in the method invocation.

该成员可被方法调用所在的类或接口访问(第6.6节). 成员方法在方法调用时是否可访问取决于访问修饰符(公共,无,受保护或私有) 在成员的声明中以及方法调用的位置 出现.

The member is accessible (§6.6) to the class or interface in which the method invocation appears. Whether a member method is accessible at a method invocation depends on the access modifier (public, none, protected, or private) in the member's declaration and on where the method invocation appears.

如果成员是具有arity为n的可变arity方法,则方法调用的arity大于或等于n-1.

If the member is a variable arity method with arity n, the arity of the method invocation is greater or equal to n-1.

如果成员是具有固定性n的固定固定性方法,则方法调用的安全性等于n.

If the member is a fixed arity method with arity n, the arity of the method invocation is equal to n.

如果方法调用包括显式类型参数,并且该成员是泛型方法,则类型参数的数量相等 方法的类型参数的数量.

If the method invocation includes explicit type arguments, and the member is a generic method, then the number of type arguments is equal to the number of type parameters of the method.

如果搜索没有产生至少一种可能适用的方法,则会发生编译时错误.

这篇关于JAVA中动态实例化的优势的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆