黑马程序员--java基础复习继承之抽象类与接口

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


接着昨天的继承下半部分

抽象(abstract)

抽象方法:当多个类中出现相同功能,但是功能主体不同,这时可以进行向上抽取。这时,只抽取功能定义,而不抽取功能主

体。这样抽取出来方法,只能通过子类复写来实现功能主体,这样的方法称为抽象方法。

而包含这个抽象方法的类就叫做抽象类。

抽象类

抽象类的特点:

1、抽象方法一定在抽象类中。

2、抽象方法和抽象类都必须abstract关键字所修饰

3、抽象类不可以用new创建对象。因为调用抽象方法没意思

4、抽象类中的方法要被使用,必须由子类复写其所有的抽象方法后建立子类对象调用。

如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类

看一段代码,看看抽象类的定义格式(抽象类中可以有非抽象方法,也可以有成员变量):

abstract class Student
{
	//抽象方法,没有功能主体
	abstract void study();
	
	//非抽象方法,子类可以直接调用,或者复写了调用。
	void sleep()
	{
		System.out.println("躺着睡");
	}
}

class BaseStudent extends Student
{
	//复写抽象类的抽象方法
	void study()
	{
		System.out.println("基础学习");
	}
}
//继承抽象类
class AdvStudent extends Student
{
	//复写抽象类的抽象方法
	void study()
	{
		System.out.println("高级学习");		
	}
}

看一个实例,理解抽象类的应用:

/*
假如我们在开发一个系统时需要对员工进行建模,员工包含三个属性:姓名、工号以及工资。
经理也是员工,除了含有员工的属性外,另外还有一个奖金属性。请使用继承的思想设计出员工类
和经理类。要求类中提供必要的方法进行属性访问。
*/


//员工类(父类)
abstract class Employee
{
	private String name;
	private String id;
	private double pay;
	
	//在构造函数中对成员变量初始化
	Employee(String name,String id,double pay)
	{
		this.name=name;
		this.id=id;
		this.pay=pay;
	}
	
	//抽象类(工作内容不确定,需要子类进行复写)
	abstract void work();
}

//普通员工类
class Pro extends Employee
{
	Pro(String name,String id,double pay)
	{
		//调用父类的构造函数
		super(name,id,pay);
	}
	//复写父类的抽象方法
	void work()
	{
		System.out.println("普通员工工作内容");
	}
}

//经理类,继承员工类
class Manager extends Employee
{
	private int bonus;
	//在构造函数中对对象的属性初始化
	Manager(String name,String id,double pay,int bonus)
	{
		super(name,id,pay);
		this.bonus=bonus;
	}
	
	//复写父类的抽象方法
	void work()
	{
		System.out.println("经理工作内容");
	}
}

class AbstractTest
{
	public static void main(String[] args)
	{
		System.out.println("抽象类的应用");
	}
}

抽象类和一般类的区别

1、抽象类和一般类没有太大的不同。该如何描述事物,就如何描述事物,只不过,该事物中多了一些看不懂的东西。这些不确定的

部分,也是该事物的功能,需要明确出现,但是无法定义主体。

2、抽象类比一般类多了抽象方法。

3、抽象类不可以实例化(即不可以创建对象)

特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。



模版方法设计模式


什么是模版方法呢?
在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,
那么这时就将不确定的部分暴露出去。由该类的子类去实现。

看下面代码中对模版方法设计模式的应用

<span style="font-size:14px;">/*
需求:获取一段程序运行的时间
原理:获取程序开始和结束的时间并相减即可

获取时间:System.currentTimeMillis();
*/

abstract class GetTime
{
	//这个功能是固定的,为避免子类复写这个功能,所以将其用final修饰
	public final void getTime()
	{
		//程度开始时间
		long start=System.currentTimeMillis();
		
		//不确定的功能部分
		runcode();
		
		//程序结束时间
		long end=System.currentTimeMillis();
		System.out.println("毫秒:"+(end-start));
	}
	
	//因为功能不确定,所以定义为抽象方法,将其暴露出去,以供子类方法重写,实现功能
	//当然,这里不是一定得是抽象方法,也可以不是抽象的,只要能让子类复写就可以
	public abstract void runcode();
}

class SubTime extends GetTime
{	
	//复写父类中的抽象方法
	public void runcode()
	{
		for(int x=0;x<4000;x++)
		{
			System.out.print(x);
		}
	}
}</span><span style="font-size:18px;">
</span>


接口

接口:初期理解,可以认为是一个特殊的抽象类。当然抽象类中的方法都是抽象的,那么该类可以通过接口的形式来

表示。

class用于定义类,interface用于定义接口

接口定义时,格式特点:
1、接口中常见定义:常量,抽象方法  (接口中的方法都是抽象的)
2、接口中的成员都有固定修饰符
常量:public static final
方法:public abstract



总结
接口中的成员都是public的

接口:是不可以创建对象的,因为有抽象方法。需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。否则子类是一个抽象类.

代码:

interface Inter
{
	//常量
	public static final int NUM=3;
	
	//抽象方法
	public abstract void show();
}

class Test implements Inter
{
	public void show(){}
}

class InterfaceDemo
{
	public static void main(String[] args)
	{
		Test t=new Test();
		System.out.println(t.NUM);
		System.out.println(Test.NUM);
		System.out.println(Inter.NUM);
		
		//t.NUM=4;//这里编译失败,因为NUM是一个常量,不能赋值
	}
}

类与接口之间的多实现implement

接口与接口是继承关系,接口之间可以多层继承,可以多继承

<span style="font-size:14px;">interface Inter
{
	//常量
	public static final int NUM=3;
	
	//抽象方法
	public abstract void show();
}

interface InterA
{
	//抽象方法
	public abstract void method();
	//抽象方法
	public abstract void show();
}

class Test implements Inter,InterA
{
	//复写接口InterA中的抽象方法method()
	public void method(){}
	
	//复写接口InterA和Inter中的抽象方法show()
	//这里可以看到类为什么不能多继承,因为多个父类有相同方法的话会引起混乱。
	//但多个接口之间有相同方法则不会,因为接口方法中都是抽象方法,没有方法体
	public void show(){}
}</span>


接口的特点:

1、接口是对外暴露的规则。
2、接口是程序的功能扩展
3、接口可以用来多实现 (降低了耦合性)
4、类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口
5、接口与接口之间可以有继承关系


所以如果实现一个体系中的基本功能时,可以用继承来实现(通过继承来调用或复写体系中的基本功能),如同学生类中有学习的基本功能,不管是小学生还是大学生,所以可以通过继承来实现。而恋爱类,则是属于扩展功能,只有大学生类才能有,而小学生则不能有,则大学生类可以通过接口的方式来实现


看下面的代码:

//抽象学生类
abstract class Student
{	
	//抽象的学习方法
	abstract void study();
	//共性内容非抽象的睡觉方法
	void sleep()
	{
		System.out.println("sleep");
	}
}

//接口,吸烟
interface Smoking
{
	void smoke();
}

//Zhangsan这个对象继承学生类,实现吸烟接口
class Zhangsan extends Student implements Smoking
{
	//复写学习方法
	void study()
	{
		System.out.println("Zhangsan_study");
	}

	//实现接口中的抽象方法,复写吸烟方法
	public void smoke()
	{
		System.out.println("Zhangsan_smoking");
	}
}

//Lisi是好学生,不吸烟
class Lisi extends Student 
{	
	//复写学习方法
	void study()
	{
		System.out.println("Lisi_study");
	}
}


class InterfaceDemo
{
	public static void main(String[] args) 
	{
		//创建两个类的实例对象
		Zhangsan z = new Zhangsan();
		z.study();
		z.smoke();
		new Lisi().study();
	}
}

结果:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值