Java的抽象类 和它的实体

问题:Java的抽象类可以实例化吗?如何实例化?

定义任何类,若在关键词class 之前加上修饰符 abstract,它就成了抽象类。抽象类不允许直接被实例化

也就是说,在任何一个能实例化的类的定义前,放上关键字 abstract ,给定类就被看作是抽象类,进而不能直接被实例化了。显然,这种抽象类中没有抽象的方法

常见的情况是,在定义一个类的时候, 一旦出现了抽象方法,这个类就是抽象的, 必须在关键字class之前放上修饰符 abstract ,否则会有编译错误

抽象,就是从许多具体事物中舍弃个别的、特殊的属性,抽出共同的、本质的属性。

定义抽象方法的必要性:

比如,定义类 Person的时候,各种人的吃饭方式各有不同:中国人用筷子吃饭, 西方人用刀叉吃饭, 或印度人用手抓着吃饭。

因此,定义吃饭方法 havingDinner()的时候,就要从多种人中舍弃个别的、具体的操作(如:用筷子吃饭, 用刀叉吃饭, 或用手抓着吃饭),抽出共同的、本质的操作:吃饭,于是 产生了抽象方法 havingDinner()。

做法是,忽略方法体(即:不在抽象方法中写一对花括号和其中的代码块)而仅给出方法的签名。就是说,只有方法的特征没有方法的实现,以构成抽象方法。

正是因为有了这一个抽象方法:吃饭, 所以 Person 就必须是抽象类,即在类定义之前必须冠以 abstract class Person, 以示它为 抽象类, 不可以直接使用 new 操作符来创建实体

然而,抽象类 Person 可以有实体。它可以通过它的子类(派生类)产生它的对象。所以,Java抽象类不可以直接 借助 操作符 new 被实例化,但它可以 通过完善了它的抽象方法定义的子类(派生类),借助 操作符 new ,产生它 (Person) 的对象。这种案例,被称作"向上转型”( Upcasting)。
其优点是,可以将多种不同子类对象的引用,储存于单一种类 (抽象类/父类 Person) 的 引用之中。案例见如下代码。

/*因为类的定义中有一个抽象方法:吃饭, 
* 所以它必须是抽象类
*/
abstract class Person { 
protected String name;
public Person(String name){
this.name=name;
  }
/* 不同人吃饭方法不一样,放在一起定义太麻烦,
 * 或不可能,因此只能冠以修饰符 abstract,
 * 随后给出方法的签名
 */
abstract String havingDinner();

static Person getInstane(){
return new Person("Noname"){
String havingDinner(){
return name + " is using unknown manner to eat. 无名氏用未知方式吃饭。";
}
};
}
}

class Chinese extends Person{ // 具体定义中国人
public Chinese(String name){
super(name);
}
public String havingDinner(){ //吃饭具体化
return name + "用筷子吃饭。";
}
}
class American extends Person{ // 具体定义美国人
public American(String name){
super(name);
}
public String havingDinner(){ //吃饭具体化
return name + "用刀叉吃饭。";
}
}
class Indian extends Person{ //具体定义印度人
public Indian(String name){
super(name);
}
public String havingDinner(){ //吃饭具体化
return name + "用手抓着吃饭。";
}
}

public class AbstractTest {
public static void main(String args[]){
Person p[]=new Person[4];
p[0] = new Chinese("李明");
p[1] = new American("特朗普");
p[2] = new Indian("桑贾伊·甘地");
p[3] = Person.getInstane();
for (Person r:p)
System.out.println(r.havingDinner());
}
} 

输出:

李明用筷子吃饭。 特朗普用刀叉吃饭。 桑贾伊·甘地用手抓着吃饭。 Noname is using unknown manner to
eat. 无名氏用未知方式吃饭。

从这个案例也可见,在抽象类 Person 的定义之中, 定义一个静态的方法 getInstane(), 调用它也可以返回一个 Person 类的对象。表面上,似乎借用抽象类 Person 的名字来调用它的静态方法,也可以实例化抽象类 Person。但进一步追究这个方法的定义就会发现,它仍然要使用 操作符 new 和一个匿名(子)类来达到实例化抽象类 Person 的目的。

“向上转型 Upcasting” 一般都可行。因为,无论中国人、美国人、还是印度人,他/她们都是人。然而,“向下转型 Downcasting”,即 “将 Person 类型的引用,强制转换成其子类的引用” 是有条件的。条件是:Person 的引用,必须是调用这个给定的子类的构造方法而创建的。这是因为:一个人不一定就是 中国人、美国人、或是印度人。

参考资料网址:https://bbs.csdn.net/topics/393715402

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值