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) 抽象类:人类; 运动员类、教练类 这两个继承人类;具体类:乒乓球队员类、教练类和篮球队员类、教练类 ; 分别继承运动员类或教练类,其中乒乓球有关的扩展学习英语接口