Java开发笔记(五十七)因抽象方法而产生的抽象类

前面介绍了类的常见用法,使人感叹面向对象的强大,几乎平常生活中的全部事物,均可以抽象成Java的基类及其子类。然而抽象操做也有反作用,就是某个抽象而来的行为多是不肯定的,好比半夜鸡叫,若是是公鸡则一定“喔喔喔”地叫,若是是母鸡则一定“咯咯咯”地叫,可要是不能肯定这只鸡是公鸡仍是母鸡抑或小鸡,系统怎么知道它会怎么叫?落实到鸡类Chicken的定义代码中,它的call方法便没法给出具体的叫声了,尽管鸡类可以派生出公鸡类和母鸡类,再在公鸡类和母鸡类重写call方法,可是外部仍然能够建立鸡类的实例,接着调用鸡类实例的call方法,此时该指望这只鸡发出什么叫声呢?不论是让鸡类胡言乱语、语无伦次,仍是让鸡类默不做声、噤若寒蝉,显然都与真实状况有很大出入。
因而可知,某些类其实并不能拿来直接使用,充其量只能算半成品,必须通过进一步的加工,造成最终的成品方能给外部调用。鉴于前述的鸡类存在叫唤这个不肯定的方法,故而理应将它纳入半成品之列;至于由鸡类派生而来的公鸡类与母鸡类,由于包括叫唤在内的每一个方法都是明确的,因此它们才成为机能鉴权的完整类。在Java编程中,功能不肯定的方法被称做抽象方法,而包含抽象方法的类受到牵连就变成了抽象类。在类的定义代码里面,经过关键字abstract来标识抽象方法及抽象类;凡是被abstract修饰的抽象方法,因为方法的具体实现并不明确,所以抽象方法没有花括号所包裹着的方法体;凡是被abstract修饰的抽象类,因为包含了至少一个抽象方法,所以不容许外部建立抽象类的实例,不然就会出现鸡类实例不知如何叫唤的尴尬。除此以外,抽象类还有下列两点须要注意:
一、abstract只能用来修饰抽象方法和抽象类,不可用于修饰成员属性,由于属性值自己就容许经过赋值来改变,无所谓抽象不抽象。
二、虽然抽象类依旧能够拥有构造方法,但它的构造方法并不能被外部直接调用,由于外部不容许经过构造方法来建立抽象类的实例,抽象类的构造方法只能提供给它的子类调用。
絮絮不休了这么多抽象概念,接着尝试把以前的鸡类改写成抽象类,修改后的抽象鸡类定义代码示例以下:html

//演示抽象类的定义
abstract public class Chicken {

	// 定义一个名称属性
	public String name;
	// 定义一个性别属性
	public int sex;
	
	// 定义一个抽象的叫唤方法。注意后面没有花括号,而且以分号结尾
	abstract public void call();

	// 即便抽象类定义了构造方法,外部也没法建立它的实例
	public Chicken() {
	}

	// Java只有抽象类和抽象方法,没有抽象属性的说法
	//abstract public String cry;
}

而后分别编写继承自鸡类的公鸡类和母鸡类,其中鸡类的抽象方法call是必须在子类中重写的,只有这样,派生而来的子类才具有全部完善的行为动做;不然的话,这个子类仍旧是个还没有完工的半成品,依然属于抽象类的行列。下面是重写了call方法的公鸡类代码例子:java

//定义一个继承自抽象鸡类的公鸡类
public class Cock extends Chicken {
	
	public Cock() {
		// 公鸡的性别固定为雄性
		sex = 0;
	}

	// 重写了公鸡的叫唤方法。若是不重写父类的抽象方法,那么该子类仍旧为抽象类
	public void call() {
		System.out.println("喔喔喔");
	}
}

一样重写了call方法的母鸡类代码以下所示:编程

//定义一个继承自抽象鸡类的母鸡类
public class Hen extends Chicken {
	
	public Hen() {
		// 母鸡的性别固定为雌性
		sex = 1;
	}

	// 重写了母鸡的叫唤方法。若是不重写父类的抽象方法,那么该子类仍旧为抽象类
	public void call() {
		System.out.println("咯咯咯");
	}
}

最后轮到外部调用各类鸡类了,对于外部而言,惟一的区别是外部不能建立抽象类的实例,其它子类的调用则跟从前同样没有变化。具体的外部调用代码见下:日志

		// 不能建立抽象类的实例,由于抽象类是个还没有完工的类
		//Chicken chicken  = new Chicken();
		// 建立一个公鸡实例,公鸡类继承自抽象类Chicken
		Cock cock = new Cock();
		cock.call(); // 调用公鸡实例的叫唤方法
		// 建立一个母鸡实例,母鸡类继承自抽象类Chicken
		Hen hen = new Hen();
		hen.call(); // 调用母鸡实例的叫唤方法

 

运行上面的调用代码,获得如下的日志结果,可见子类重写后的call方法正常工做。htm

喔喔喔
咯咯咯

  

更多Java技术文章参见《Java开发笔记(序)章节目录对象

相关文章
相关标签/搜索