写给自己的JAVA工程师之路-抽象类

1 抽象类


1.1 抽象类的基本概念

如果说现在在一个类之中需要定义一个没有方法体的一个方法,那么可以利用abstract关键字来进行抽象方法的定义,而包含有抽象方法的类就可以使用abstract来定义成为抽象类。
假如说有一个A类在设计之初有一个要求,希望继承他的子类一定要覆写他的方法。但事实上,这个时候的子类完全可以灵活的选择是否覆写方法。但是由于只是一个普通方法,所以对于子类是否覆写没有任何的要求,于是这样就会出现一个漏洞,父类无法强制要求子类覆写方法。 如果只依靠普通类的继承,那么根本就不能对子类产生限制,所以就可以利用抽象类和抽象方法来解决此类问题。

抽象类无法实例化。(即使没有抽象方法)

抽象类的子类(如果不是抽象类),那么必须要覆写抽象类中的全部抽象方法。

抽象类可以利用对象的向上转型机制,通过子类对象进行实例化操作。

抽象类不能使用final关键字来定义,因为抽象类必须有子类,而final不能子类。

外部抽象类上不允许使用static声明,但是内部抽象类中可以使用static声明,这样表明的是一个外部抽象类。

abstract class A{
	public  abstract void printA();
	static abstract class B{
		public abstract void printB();
	}
}

class B extends A.B{
	@Override
	public void printB() {
		
	}
}

抽象类中可以存在static方法,而且static方法不受实例化对象控制。

abstract class A{//此类实际之初考虑以后发展需要有子类
	public  abstract void printA();
	private static class B extends A{//在A类里面直接定义实现子类
			public void printA(){
				System.out.println("Hello World");
			}
	}
	public static A getInstance(){
		return new B();
	}
}

public class AbstractDemo {
	public static void main(String[] args) {
		A a=A.getInstance();
		a.printA();
	}
}

抽象类就是比普通类多了抽象方法而已,但是普通类中的所有结构抽象类都可以定义,包括:普通方法,构造方法,属性,常量。而且子类对象也符合于对象实例化流程,默认先调用父类中的无参构造方法,而后在执行子类自己的构造操作。

abstract class A{
public static final String INFO="HELLO";//常量
public A(){
this.fun();
}
public void fun(){
System.out.println("***************");
}
public  abstract void print();//没有方法体
}


class B extends A{
public void print(){
System.out.println("强制覆写的方法");
}
}


public class AbstractDemo {
public static void main(String[] args) {
A a=new B();//向上转型
a.print();
}
}

抽象类与普通类相比最大的好处就是强制定义了子类的实现要求。

本质上讲抽象类就是比普通类多了一些抽象方法的定义而已。

在实际的设计之中,父类的设计是最重要的,普通类与抽象类相比,明显抽象类的约束更加的严格,所以在实际的开发之中,几乎不会出现普通类定义子类的情况,大多数都是继承抽象类。

思考:
abstract class A{
	public A(){//2 默认调用父类构造
		this.print();// 3 调用PRINT()方法
	}
	public  abstract void print();
}

class B extends A{
	private int num=50;
	public B(int num){//1 内容传递过来,在子类对象实例化之前先实例化父类对象
		this.num=num;
	}
	public void print(){//4 调用此方法执行,但是此时子类对象还没有实例化
		System.out.println(num);
	}
}

public class AbstractDemo {
	public static void main(String[] args) {
		new B(100);// 结果 0
	}
}

子类对象实例化之前一定要先实例化父类对象,也就是说此时,子类对象的属性都没有内容。

1.2 抽象类的实际应用-模板设计模式

abstract class Action{
	
	public abstract void eat();
	public abstract void sleep();
	public abstract void work();
}
class People extends Action{

	@Override
	public void eat() {
		System.out.println("人在吃饭");
	}

	@Override
	public void sleep() {
		System.out.println("人在休息");
	}

	@Override
	public void work() {
		System.out.println("人在工作");
	}
	
}
class Robot extends Action{

	@Override
	public void eat() {
		System.out.println("机器人在充电");
	}

	@Override
	public void sleep() {
	}

	@Override
	public void work() {
		System.out.println("机器人在工作");
	}
	
}
class Pig extends Action{

	@Override
	public void eat() {
		System.out.println("猪在进食");
	}

	@Override
	public void sleep() {
		System.out.println("猪在睡觉");
	}

	@Override
	public void work() {}
	
}
public class AbstractDemo {
	public static void main(String[] args) {
		fun(new Pig());
		System.out.println("***************");
		fun(new People());
		System.out.println("***************");
		fun(new Robot());
		System.out.println("***************");
	}
	public static void fun(Action action){
		action.eat();
		action.sleep();
		action.work();
	}
}

现在在整个程序之中,如果某一类事物需要实现特定功能,那么就必须按照Action所定义的方法进行覆写。这个时候子类必须按照父类提供的
模板编写代码。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值