Java - 抽象类和接口

版权声明:call me 刘英雄 https://blog.csdn.net/weixin_42526141/article/details/82837514

1、抽象类:抽象类用关键字abstract修饰,简单的说,抽象类是一个不能实例化的类,它可以具有抽象方法或者普通方法

抽象类优势:

  • 抽象类可以将已经实现的方法提供给其子类使用,使代码可以被复用
  • 抽象类中的抽象方法在子类中重写,保证了子类还具有自身的独特性
  • 抽象类指向其子类的对象,可以实现多态

普通方法和抽象方法的区别:

  • 普通方法必须要有方法体,抽象方法不能有方法体(大括号也没有)
  • 抽象方法要用abstract修饰
  • 抽象方法必须存在于抽象类中

2、接口:java中的接口是一种约定,规定了实现该接口的类必须遵循一定规则,规则体现在“抽象方法”上,所以说:接口是抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法,用关键字implements实现

接口中可以含有 变量和方法。接口中的变量会被隐式地指定为public static final变量;而方法会被隐式地指定为public abstract方法;

并且接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法。

从这里可以隐约看出接口和抽象类的区别,接口是一种极度抽象的类型,它比抽象类更加“抽象”

3、接口和抽象类的区别:

  • 抽象类使用abstract声明,接口使用interface声明
  • 抽象类可以包含抽象方法(必须使用abstract关键字)和普通方法
  • 接口只能包含抽象方法(无须使用abstract关键字)
  • 一个类只能继承一个父类,但能同时实现多个接口,也可以同时继承抽象类和实现接口

实验:某人是软件工程师,能编写代码,完成项目功能,又是音乐家,能作曲唱歌,如何用java代码体现

分析:定义人类作为抽象父类,包含人的基本属性和行为;定义编程接口,拥有编程能力;定义作曲接口,拥有作曲能力等;定义一个子类,继承人类,同时实现编程接口和作曲接口。

Human类:封装Human类,用private修饰属性,定义人类公有的属性name,age,sex;公有的方法work(),并提供set和get方法以及构造器。

package com.liudm.test5;

public abstract class Human {
	private String name;
	private int age;
	private char sex;
	public abstract void work();
	
	public Human() {
		// TODO Auto-generated constructor stub
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public char getSex() {
		return sex;
	}
	public void setSex(char sex) {
		this.sex = sex;
	}
}

Programe类:抽象方法,完成编程功能的定义

package com.liudm.test5;

public interface Programe {
	public void programing();

}

Compose类:抽象方法,完成作曲家的功能定义

package com.liudm.test5;

public interface Compose {
	public void sing();
}

Person类:新建Person,该类继承Human抽象类,让他实现Programe、Compose接口,重写抽象方法,从而通过代码的形式体现了人对象拥有了很多能力。

package com.liudm.test5;

public class Person extends Human implements Programe,Compose{
	public void work(){
		System.out.println("人都要工作");
	}
	public void programing(){
		System.out.println("有的人会编程");
	}
	public void sing(){
		System.out.println("有的人会唱歌");
	}
}

Test类:

package com.liudm.test5;

public class Test {
	public static void main(String[] args) {
		Human man = new Person();
		man.work();
		Person per = (Person)man;
		per.programing();
		per.sing();
	}
}


练习1: 需求说明:实现某公司各种岗位(经理、销售人员、普通员工)的员工薪水计算,输出不同岗位各一名员工的工资。要求使用抽象类实现。
分析:定义员工抽象类,具有计算薪水的抽象方法;定义子类:经理类、销售人员类、普通员工类,分别继承员工抽象类,重写计算薪水的方法;定义测试类,包含输出薪水的方法,参数为员工对象(抽象父类的引用指向子类的对象,实现多态)。

 Staff类:

package com.liudm.demo8;

public abstract class Staff {
	private double salary;
	public abstract void Wage();
	
	public Staff(){
		super();
	}
	public void Staff(double salary){
		this.salary = salary;
	}

	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
}

Manager类:

package com.liudm.demo8;

public class Manager extends Staff{
	@Override
	public void Wage() {
		// TODO Auto-generated method stub
		System.out.println("经理的薪水是:" + (this.getSalary() + 3000));
	}
}

Saler类:

package com.liudm.demo8;

public class Saler extends Staff{
	@Override
	public void Wage() {
		// TODO Auto-generated method stub
		System.out.println("销售人员的薪水是:" + (this.getSalary() + 2000));
	}

}

Employee类:

package com.liudm.demo8;

public class Employee extends Staff{
	@Override
	public void Wage() {
		// TODO Auto-generated method stub
		System.out.println("普通员工的薪水是:" + (this.getSalary() + 1000));
	}

}

测试类:

package com.liudm.demo8;

public class StaffTest {
	public static void main(String[] args) {
		Staff manager = new Manager();
		Staff saler = new Saler();
		Staff employee = new Employee();
		
		manager.setSalary(7000);
		manager.Wage();
		saler.setSalary(5000);
		saler.Wage();
		employee.setSalary(3000);
		employee.Wage();
		
	}
}

 

练习2: 需求说明:在职研究生既要学习,还要工作,使用实现多个接口的方式定义研究生类
分析:定义人类作为抽象父类,包含人的基本属性和行为;定义学习接口,拥有学习能力;定义工作接口,拥有工作能力等;定义研究生类,继承人类,同时实现学习接口和工作接口。

Person类:

package com.liudm.demo9;

public abstract class Person {
	private String name;
	private int age;
	private char sex;
	
	public Person(){
		super();
	}
	public Person(String name,int age,char sex){
		super();
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public char getSex() {
		return sex;
	}
	public void setSex(char sex) {
		this.sex = sex;
	}
}

Study接口:

package com.liudm.demo9;

public interface Study {
	public void Study();
}

Work接口:

package com.liudm.demo9;

public interface Work {
	public void Work();
}

Student类:

package com.liudm.demo9;

public class Student extends Person implements Study,Work{
//	public void Student(String name,int age,char sex){
//		super(name,age,sex);
//	}

	@Override
	public void Study() {
		// TODO Auto-generated method stub
		System.out.println(this.getName() + "\t" + this.getAge() + "\t" + this.getSex() + "\t" + "能够学习");
	}
	@Override
	public void Work() {
		// TODO Auto-generated method stub
		System.out.println(this.getName() + "\t" + this.getAge() + "\t" + this.getSex() + "\t" + "能够工作");
	}
}

测试类:

package com.liudm.demo9;

public class PerTest {
	public static void main(String[] args) {
		Student stu1 = new Student();
		Student stu2 = new Student();
		stu1.setName("Sara");
		stu1.setAge(20);
		stu1.setSex('女');
		stu2.setName("Jonson");
		stu2.setAge(24);
		stu2.setSex('男');
		
		stu1.Study();
		stu2.Work();
	}
}

练习3: 教练和运动员案例:乒乓球运动员和篮球运动员;乒乓球教练和篮球教练。 为了出国交流,跟乒乓球相关的人员都需要学习英语。
请用所学知识分析:这个案例中有哪些抽象类,哪些接口,哪些具体类。
分析:
1) 共同的属性:姓名 年龄;共同的方法:吃饭,睡觉(其中吃饭的内容两者不同,所以用抽象方法);不同的方法:队员练习,教练教导,分别写入队员类和教练类
2) 接口:学习英语
3) 抽象类:人类;  运动员类、教练类 这两个继承人类;具体类:乒乓球队员类、教练类和篮球队员类、教练类 ; 分别继承运动员类或教练类,其中乒乓球有关的扩展学习英语接口

猜你喜欢

转载自blog.csdn.net/weixin_42526141/article/details/82837514