将实例化分配给父类和派生类之间的区别

时间:2015-09-07 08:45:24

标签: java

如果我宣布这两个类:

public class A {
  // attributes
}
public class B extends A {
  // attributes
}

A obj1 = new B();
B obj2 = new B();

这两个实例之间有什么区别?

3 个答案:

答案 0 :(得分:2)

实例化是相同的。在这两种情况下,您都要创建 -----------------------------------com.example.Contact.java----------------------------------- package com.example; import javax.annotation.Generated; import com.google.gson.annotations.Expose; @Generated("org.jsonschema2pojo") public class Contact { @Expose private String id; @Expose private String name; @Expose private String email; @Expose private String address; @Expose private String gender; @Expose private Phone phone; /** * * @return * The id */ public String getId() { return id; } /** * * @param id * The id */ public void setId(String id) { this.id = id; } /** * * @return * The name */ public String getName() { return name; } /** * * @param name * The name */ public void setName(String name) { this.name = name; } /** * * @return * The email */ public String getEmail() { return email; } /** * * @param email * The email */ public void setEmail(String email) { this.email = email; } /** * * @return * The address */ public String getAddress() { return address; } /** * * @param address * The address */ public void setAddress(String address) { this.address = address; } /** * * @return * The gender */ public String getGender() { return gender; } /** * * @param gender * The gender */ public void setGender(String gender) { this.gender = gender; } /** * * @return * The phone */ public Phone getPhone() { return phone; } /** * * @param phone * The phone */ public void setPhone(Phone phone) { this.phone = phone; } } -----------------------------------com.example.Example.java----------------------------------- package com.example; import java.util.ArrayList; import java.util.List; import javax.annotation.Generated; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; @Generated("org.jsonschema2pojo") public class Example { @SerializedName("first_name") @Expose private String firstName; @Expose private List<Contact> contacts = new ArrayList<Contact>(); /** * * @return * The firstName */ public String getFirstName() { return firstName; } /** * * @param firstName * The first_name */ public void setFirstName(String firstName) { this.firstName = firstName; } /** * * @return * The contacts */ public List<Contact> getContacts() { return contacts; } /** * * @param contacts * The contacts */ public void setContacts(List<Contact> contacts) { this.contacts = contacts; } } -----------------------------------com.example.Phone.java----------------------------------- package com.example; import javax.annotation.Generated; import com.google.gson.annotations.Expose; @Generated("org.jsonschema2pojo") public class Phone { @Expose private String mobile; @Expose private String home; @Expose private String office; /** * * @return * The mobile */ public String getMobile() { return mobile; } /** * * @param mobile * The mobile */ public void setMobile(String mobile) { this.mobile = mobile; } /** * * @return * The home */ public String getHome() { return home; } /** * * @param home * The home */ public void setHome(String home) { this.home = home; } /** * * @return * The office */ public String getOffice() { return office; } /** * * @param office * The office */ public void setOffice(String office) { this.office = office; } }

分配是不同的。由于new B()B,因此您可以将A类型的任何表达式分配给B类型的变量。这可以在不需要进行显式转换的情况下发生,因为assignment contexts (JLS 8 § 5.2)

  

允许将表达式的值赋给变量;必须将表达式的类型转换为变量的类型。

在您的示例中,执行了widening reference conversion (JLS 8 § 5.1.5),允许将引用类型A转换为引用类型S,前提是TS的子类型1}}。编译器会自动为您执行此操作,因为它是一个扩展转换:即,如果没有T,它将始终成功。

Java需要允许此操作才能执行Polymorphism,这样您就可以将类型ClassCastException视为任何超类型S(例如将TCat视为Dog);这反过来允许您将常见行为(或常见合同 - 请参阅下面的有关接口的注释)放入超类型中。

在运行时,实际类型是已知的,并且调用实际类型的方法而不是超类型方法。因此,对于Animal,运行时知道Animal a = new Cat();a并在Cat上调用sleep的实现,而不是Cat。< / p>

Animal

这整个概念也适用于允许您将共同契约应用于不共享超类型关系的对象的接口:

public class Animal { public void sleep() { /* close eyes */ } }
public class Cat extends Animal { public void sleep() { /* curlUpAndSleep */ } }
public class Dog extends Animal { public void sleep() { /* stretchOutAndSleep */ } }
...
public void putToBed(Animal a) { a.sleep(); }
...
Animal a1 = new Cat(); // curls up and sleeps
Animal a2 = new Dog(); // stretches out and sleeps - my dog obviously thinks he's a cat
putToBed(a1); putToBed(a2);

答案 1 :(得分:0)

以防

A a = new B()

创建了类型B的Instace但是refference是父类型。使用它,您无法访问特定于B类型的字段或调用方法。

答案 2 :(得分:0)

让我在你的问题中添加一些代码......

public class A{
void base(){
 print("base method");
}
}
public class B extends A{
void child(){
 print("child method");
}
}
.......

A obj1 = new B(); 
B obj2 = new B();

现在按对象调用两个方法

obj1.base();   //base method

obj1.child();   //create compile time error 

因为obj1是B类的对象,但引用是A类....
obj1只能调用A类中的方法

//but obj2 can call both methods as it inherits Class A and also having reference of its own.

obj2.base();   //base method

obj2.child();   // child method