2.17学习记录 抽象类的应用

内容来自《第一行代码》,很简单易懂
2.抽象类应用—模板设计模式
在本程序中定义抽象类A 的时候根本不知道具体要实现的子类是什么,但是强制子类来覆写print(),当调用fun()方法时,执行的一定是被子类所覆写的抽象方法,具体子类怎么实现由子类来决定。

abstract class A {          //定义一个抽象类
	public void fun(){		//此为普通方法
		this.print();		//在普通方法中直接调用抽象方法
		}
		public abstract void print();  //此为抽象方法
	}
class X extends A{			//抽象类必须有子类
	public void print(){
	System.out.println("更多课程请访问:www.yootk.com");
	}
}
public class TestDemo{
	public static void main(String args[]){
	A a = new X();  	//通过子类实例化抽象类对象
	a.fun();            //抽象类中的普通方法
	}
}	

再对上面的例子进行扩写。

abstract class Action{//定义一个抽象的行为类,行为不是具体的
//定义常量必须保证两个内容相加的结果不是其他行为,例如:EAT + SLEEP 的结果是6,不会和其他值冲突
	public static final int EAT = 1;  //吃
	public static final int SLEEP = 5; //睡
	public static fianl int WORK = 7;//工作
//控制操作的行为,所有的行为都通过类中的常量描述,可以使用			       			  EAT,SLEEP,WORK,或者叠加使用,例如:边吃边工作,使用EAT+Work来描述 @param flag 操作的行为标记//

public void command(int flag){
	switch(flag){  //switch只支持数值判断,而if支持条件判断
	case EAT:		//当前为吃的操作
	this.eat();		//调用子类中具体的吃方法
	break;
	case SLEEP:
	this.sleep();
	break;
	case WORK:
	this.work();
	break;
	case SLEEP + WORK;  // 组合方法
	this.sleep();
	this.work();
	break;
	}
}

public static void eat();  //定义子类的操作标准
public static void sleep();
public static void work();
}

class Robot extends Action{//定义机器人的行为子类
	public void eat(){//覆写行为操作
		System.out.println("机器补充能量");
	}
	public void sleep(){//此方法不需要但必须覆写,所以方法为空
	}
	public void work(){
		System.out.println("机器要工作");
	}
}

class Human extends Action{
	public void eat(){
		System.out.println("人类要吃东西")}
	public void sleep(){
		System.out.println("人类要睡觉");
	}
	public void work(){
		System.out.println("人类要工作");
	}
}

calss Pig extends Action{
	public void eat(){
		System.out.println("猪要吃东西");
	}
	public void sleep(){
		System.out.println("猪要睡觉");
	}
	public void work(){
	}
}

public class TestDemo{
	public static void main(String args[]){
	fun(new Robot());//传递机器人行为子类
	fun(new Human());//传递人类行为子类
	fun(new Pig());//传递猪的行为子类
}
 
   //执行具体的操作行为,假设本处只执行EAT,SLEEP,WORK,3个行为
   //@param act 具体的行为对象
public static void fun(Action act){
	act.command(Action.EAT);
	act.command(Action.SLEEP);
	act.command(Action.WORK);
	}
}

接口:抽象类可以由子类实现对父类方法的覆写,但是抽象类有一个缺陷,就是只能单继承,为了解决单继承这个缺点,定义了接口这个概念。同时在开发过程中为了将具体代码的实现细节对调用处进行隐藏,也可以用接口来进行方法视图的描述。

interface A {//定义接口
	public static final String MSG = "YOOTK";//全局变量
	public static void print();//抽象方法
}

省略写法:

interface A{
	String MSG = "HELLO";
	void print();
}

(1)接口是一种特殊的类,由抽象方法和全局变量组成。上述程序定义了一个接口A,一个抽象方法(print())和一个全局变量(MSG)。
(2)由于接口中含有抽象方法,所以不能直接使用关键字new进行实例化操作,因此接口具有以下使用原则:
1)接口必须有子类,但是此时一个子类可以使用implements关键字实现多个接口,避免单继承局限。
2)接口的子类(如果不是抽象类),必须要覆写接口中的全部抽象方法。
3)接口的对象可以利用子类对象的向上转型进行实例化操作。
4)接口就是用来被继承和实现的,所以修饰符一般是public.
一个简单的继承的例子:

interface A{ //定义接口
	public static final Sring MSG = "YOOTK";//全局常量
	public abstract void print(); //抽象方法
}

interface B{
	public abtract void get();
}

class X implements A,B{
	public void print(){
		System.out.println("A接口的抽象方法!");
	}
	
	public void get(){
		System.out.println("B接口的抽象方法!");
	}
}

public class TestDemo{
	public static void main(String args[]){
	X x = new X();
	A a = x;
	B b = x;
	a.print();
	b.get();
	System.out.println(A.MSG);
	}
}

程序执行结果:
A接口的抽象方法!
B接口的抽象方法!
YOOTK

(3)一个程序既要实现继承抽象类又要实现接口,那么应该采用先继承后实现接口的顺序完成。
(4)接口里面可以定义普通内部类,抽象内部类,内部接口。

学习过程中遇到的补充知识1:java中,instanceof运算符的前一个操作符是一个引用变量,后一个操作数通常是一个类(可以是接口),用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。如果是返回true,否则返回false。

补充知识2:Spring开发框架的设计核心理念《第一行代码》的书中p249已经为读者分析了new关键字在直接实例化接口上所带来的问题。实际上这种耦合问题在很多项目开发中都会出现,很多开发者在面对这种耦合问题时,往往会采用大量结构设计进行回避,可是这样的代码维护成本太高了。所以在java开发中有一个spring框架,其核心就是解决这种代码耦合问题。

发布了48 篇原创文章 · 获赞 9 · 访问量 7912

猜你喜欢

转载自blog.csdn.net/trh_csdn/article/details/104363937