十、JAVA抽象类的定义使用

抽象类的基本概念

    抽象方法,只声明而未实现的方法我们称为抽象方法,所有的抽象方法都需要用abstract关键字声明,包含抽象方法的类也需要使用abstract关键字声明,抽象类和普通类相比,区别在于抽象类带有抽象方法,抽象方法可以只声明,而不需要方法体,具体的方法体可以子类继承后在写,这样就会变得十分方便举个例子

代码演示:

package demo;

public abstract class People{
	private String name;
	//声明抽象方法,没有方法体,直接分号结束
	public abstract void talk();
	public void eat(){
		System.out.println(name+"正在学习");
	}
}

代码讲解:上述代码我们定义一个抽象方法talk,方法和类名都是abstract修饰,抽象方法没有方法体,直接分号结束。抽象类还能够定义普通方法eat()。


抽象类定义规则:

    1.抽象类和抽象方法必须用abstact关键字来修饰

    2.抽象类不能直接实例化,也就是不能直接使用new关键字产生对象

    注意:在前一章多态中,我们介绍过向上转型,我们说过可以声明父类对象,然后通过动态绑定,将子类对象赋值给父类对象,这样父类对象就可以引用子类对象的方法,而抽象类不能直接实例化,这样我们就可以通过子类对象来给抽象类的父类实例化了。

People p = new People();       //错误,People是抽象类,无法实例化

    3.抽象方法定义时,只需要声明,不需要实现

    4.含抽象方法的类必须被声明为抽象类,抽象类的子类必须实现所有的抽象方法后,才能被实例化,否则这个子类还是个抽象类


提示:

大家注意到,子类继承父类,也会继承下父类的访问权限为公有的方法,然后子类使用同样的方法名,而执行自己的方法体,我们称为方法的重写(override),这里我们就注意到,子类在继承抽象类后,我们来完成方法体,用的是“实现”而不是“重写”。这里很容易明白,抽象方法里本来就没有方法,子类继承后写方法体,用“实现”会比用“重写”合理


抽象类的用法

//定义一个抽象类People,定义两个Student,Teacher子类,继承People

代码演示:

package demo;

abstract class People{
	private String name;
	private int age;
	
	//声明一个抽象方法talk()
	public abstract void talk();
}

class Student extends People{
	private String name;
	private int age;
	
	public Student(String name,int age){
		this.name = name;
		this.age = age;
	}

	public void talk() {
		System.out.println("学生--->姓名:"+this.name+",年龄"+this.age);
	}	
}

class Teacher extends People{
	private String name;
	private int age;
	
	public Teacher(String name,int age){
		this.name = name;
		this.age = age;
	}

	public void talk() {
		System.out.println("老师--->姓名:"+this.name+",年龄"+this.age);
	}	
}

public class AbstractDemo{
	public static void main(String[] args) {
		Student stu = new Student("dodo", 22);
		Teacher tea = new Teacher("MCwang", 32);
		stu.talk();
		tea.talk();
	}
} 

代码结果:

学生--->姓名:dodo,年龄22
老师--->姓名:MCwang,年龄32

需求提出:看到上述代码,我们发现父类People,子类Student,Teather都定义了属性name,age,并且两个子类都写了自己的构造方法,这里重复的代码量挺多的,如果我们又更多的子类,写起来就很麻烦,回到继承的章节里,我们说过子类可以继承父类的所有公有的方法,也能继承父类的私有的属性,但需要通过别的方法去调用和获取,在java中,抽象类中可以有自己的构造方法,但这些构造方法需要通过子类去调用,因为抽象类不能直接实例化。接下来我们修改代码

代码演示:

package demo;

abstract class People{
	String name;
	int age;
	
	//定义抽象类的构造方法
	public People(String name,int age){
		this.name = name;
		this.age = age;
	}
	
	//声明一个抽象方法talk()
	public abstract void talk();
}

class Student extends People{
	
	public Student(String name,int age){
		//子类构造方法通过super()调用父类的构造方法
		super(name, age);
	}

	public void talk() {
		System.out.println("学生--->姓名:"+this.name+",年龄"+this.age);
	}	
}

class Teacher extends People{
	
	public Teacher(String name,int age){
		//子类构造方法通过super()调用父类的构造方法
		super(name, age);
	}

	public void talk() {
		System.out.println("老师--->姓名:"+this.name+",年龄"+this.age);
	}	
}

public class AbstractDemo{
	public static void main(String[] args) {
		Student stu = new Student("dodo", 22);
		Teacher tea = new Teacher("MCwang", 32);
		stu.talk();
		tea.talk();
	}
} 

代码讲解:我们拿掉了子类的属性定义,在子类中通过super关键字调用父类的构造方法来实例化,然后talk()方法里又需要对属性获取和输出,所以我们将父类属性的修饰符private拿掉了,让他默认为default。这样子类才能使用到父类的属性,但是如果我们为了安全还需要再一次修改代码

代码演示:

package demo;

abstract class People{
	private String name;
	private int age;
	
	//定义抽象类的构造方法
	public People(String name,int age){
		this.name = name;
		this.age = age;
	}
	

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setAge(int age) {
		this.age = age;
	}



	//声明一个抽象方法talk()
	public abstract void talk();
}

class Student extends People{
	
	public Student(String name,int age){
		//子类构造方法通过super()调用父类的构造方法
		super(name, age);
	}

	public void talk() {
		System.out.println("学生--->姓名:"+this.getName()+",年龄"+this.getAge());
	}	
}

class Teacher extends People{
	
	public Teacher(String name,int age){
		//子类构造方法通过super()调用父类的构造方法
		super(name, age);
	}

	public void talk() {
		System.out.println("老师--->姓名:"+this.getName()+",年龄"+this.getAge());
	}	
}

public class AbstractDemo{
	public static void main(String[] args) {
		Student stu = new Student("dodo", 22);
		Teacher tea = new Teacher("MCwang", 32);
		stu.talk();
		tea.talk();
	}
} 

代码讲解:

            我们做出如下修改:在父类里属性私有化,我们在父类中提供getter()/setter()方法,这样我们在子类里就可以通过getter()/setter()方法获取到父类私有属性的值啦O(∩_∩)O。

    总结点评:面向三大特征中,封装、继承、多态,在本章节中都能得到一定的实现,前面章节还不熟悉或者忘记得同学可以倒回去看一下,当复习。抽象类我们就讲到这里。欢迎大家在下方评论提出问题或者提出建议,bigdodo一定会及时给予回复。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值