Java的抽象类 和 它的极致情况:接口
博客专区 > tcxu 的博客 > 博客详情
Java的抽象类 和 它的极致情况:接口
tcxu 发表于6个月前
Java的抽象类 和 它的极致情况:接口
  • 发表于 6个月前
  • 阅读 10
  • 收藏 0
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

摘要: Java的抽象类 和 它的极致情况:接口 abstract class & his extreme case: interface 以代码为例,概述 以下概念: 抽象、抽象方法、抽象类 以及 接口。

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

抽象类 定义任何类,若在关键词class 之前加上修饰符 abstract,它就成了抽象类。抽象类不允许被实例化。就是说,在任何一个能实例化的类的定义前,放上关键字 abstract ,给定类就被看作是抽象类,进而不能实例化。显然,这种抽象类中是没有抽象的方法。常见的情况是,在定义一个类的时候, 一旦出现了抽象方法,这个类就是抽象的, 必须在关键字class之前放上修饰符 abstract ,否则会有编译错误。

抽象方法 的产生:抽象类Person中的方法吃饭 havingDinner(),就是从许多种人中舍弃个别的、具体的操作(如用筷子吃饭, 用刀叉吃饭, 或用手抓着吃饭),抽出共同的、本质的操作:吃饭, 产生了抽象方法 havingDinner()。 做法是,忽略方法体(即不包括一对花括号和其中的代码块)而仅给出方法的签名。就是说,只有方法的特征没有方法的实现,以构成抽象方法。

//因为有一个抽象方法:吃饭, 所以是抽象类
abstract class Person { 
	protected String name;
	public Person(String name){
	this.name=name;
 	}
/* 这里,不同人吃饭方法不一样,没有统一定义,
 * 这时,只能在方法签名之前冠以关键字 abstract
 */
	abstract String havingDinner();
}

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[3];
	p[0] = new Chinese("李明");
	p[1] = new American("特朗普");
	p[2] = new Indian("桑贾伊·甘地");
	for (Person r: p)
	System.out.println(r.havingDinner());
	}
}

输出:

李明用筷子吃饭。
特朗普用刀叉吃饭。
桑贾伊·甘地用手抓着吃饭。

 

抽象方法不能被调用。它必须通过实现, 有了方法体,才可以被调用的方法。因此, 定义中国人,美国人,和 印度人的时候,继承了 抽象类 Person, 并且分别具体定义了各自吃饭的方法。这样,才可以创建对应的实体, 并调用各自的吃饭方法(函数)。

可见, 抽象方法,抽象类和接口是Java语言对抽象类概念支持的机制,显示强大的面向对象程序设计能力。

接口      如果,一个抽象类中的方法,全部是抽象的,同时,数据成员全部都是最终变量,那么,这个抽象类就成了接口,可以被其它类实现。

抽象方法必须在抽象类或接口之中。抽象类是用来被类继承的。接口是用来被类实现的。Java 允许一个类只能继承另一个类(单继承),但允许一个类同时实现多个接口。

如果子类是非抽象的,即能够产生对象的类,那么它就必须实现父类中所有的抽象方法。 否则,它仍然是抽象类,因为它所继承的方法中,仍有抽象的方法。

一旦一个类中有了抽象方法,所在类就是抽象的,类的定义前必须放上修饰符 abstract ,否则会有编译错误。

Java接口(interface), 是抽象类的极端情况,JDK1.7 及以前版本的规定,它只有抽象方法,  就是说,仅有方法的签名,没有方法的实现,为的是让这些方法今后可以在不同地点被不同的类实现。 而JDK1.8添了新规:接口还可以有默认的 和/或 静态的方法。

在Java接口(interface)中 可以定义属性/字段, 但它们必须是常量/最终变量。

如下例, PI 值在抽象类 abstract TwoD中可以定义为变量,但若要在接口 interface ThreeD 里, PI值必须定义为常量。

一个普通的类要继承(extends)抽象类,和/或者 实现(implements) 接口,就必须完成所有抽象方法的方法体的定义。广义讲,都是“父子”(传承)关系。

最后的例子显示,圆柱体类 (class  Cylinder )如何 继承 抽象类 ( abstract class TwoD), 并 实现 接口(interface ThreeD),从而成为一个可以生成实体的普通类。

abstract class TwoD {
	double PI=3.14; //若在接口中出现,必须定义为最终变量,即常量
	abstract double area();
	abstract String dimension();
}
interface ThreeD {
	double volume();
	String dimension();
}

class Cylinder extends TwoD implements ThreeD {
	int radius;
	int height;
	public Cylinder (int r, int h){
		this.radius=r;
		this.height=h;	
	}
	public double volume(){
		return PI*radius*radius*height;
	}
	public double area(){
		return 2*radius*PI*(height+radius);
	}
	public String dimension(){
		return "三维物体";
	}
	
	public String toString(){
		String s= dimension();
		s += "\n圆柱体 半径:" + radius;
		s += ", 高: " + height;
		s += "\n体积: " + volume();
		s += ", 表面积: " + area();
		return s;
	}
}
public class InterfaceAbstractClass {
	public static void main(String args[]){
	Cylinder c = new Cylinder(2,1);
	System.out.println(c.toString());
	}
}

输出:

三维物体
圆柱体 半径:2, 高: 1
体积: 12.56, 表面积: 37.68

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 15
博文 4
码字总数 4229
×
tcxu
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: