抽象类
概述:做子类共性功能抽取时,有些方法在父类中并没有具体的体现
在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
特点
1、抽象类和抽象方法必须使用 abstract 关键字修饰
//抽象类的定义
public abstract class 类名 {}
//抽象方法的定义
public abstract void eat();
2、抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
3、抽象类不能实例化(需要实例化:参照多态的方式,通过子类对象实例化,这叫抽象类多态 )
4、抽象类的子类(重写抽象类中的所有抽象方法 、或者是抽象类 )
成员特点
成员变量:可以是变量、可以是常量
构造方法:空参构造、有参构造
成员方法:抽象方法、普通方法
1.按要求实现下列问题:
1) 动物类Animal包含了抽象方法 abstract void shout();
2) Cat类继承了Animal,并实现方法shout,打印“猫会喵喵叫”
3) Dog类继承了Animal,并实现方法shout,打印“狗会汪汪叫”
4) 在测试类中实例化对象Animal a1 =new Cat(),并调用a1的shout方法
5) 在测试类中实例化对象Animal a2 =new Dog(),并调用a2的shout方法
public abstract class Animal {
public abstract void shout();
}
public class Cat extends Animal {
@Override
public void shout(){
System.out.println("猫会喵喵叫");
}
}
public class Dog extends Animal {
@Override
public void shout(){
System.out.println("狗会汪汪叫");
}
}
public class AnimalDemo {
public static void main(String[] args) {
Animal a1 =new Cat();
a1.shout();
Animal a2 =new Dog();
a2.shout();
}
}
题目2
2./*定义一个抽象类Person,
有name,age,sex三个属性,创建构造函数,给这三个属性赋值,重写打印描述信息方法,打印三个属性值;这个类中有两个抽象方法work和hello;
定义两个子类Teacher,Student;教师的work实现是:教书育人,hello实现是:“同学好”;
学生的work实现是:认真学习,hello实现是“老师好”。*/
public abstract class Person {
String name;
int age;
String sex;
public Person() {
}
public Person(String name, int age, String sex) {
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public void work(){}
public void hello(){}
public void show() {
System.out.println(name + "," + age + "," + sex);
}
}
public class Teacher extends Person{
public Teacher() {
}
public Teacher(String name, int age,String sex) {
super(name, age,sex);
}
@Override
public void work(){
System.out.println("教书育人");
}
public void hello(){
System.out.println("同学好");
}
}
public class Student extends Person{
public Student() {
}
public Student(String name, int age,String sex) {
super(name, age, sex);
}
@Override
public void work(){
System.out.println("认真学习");
}
public void hello(){
System.out.println("老师好");
}
}
public class PersonDemo {
public static void main(String[] args) {
Person p1=new Teacher();
p1.setName("张三");
p1.setAge(30);
p1.setSex("男");
p1.show();
p1.work();
p1.hello();
Person p2=new Student();
p2.setName("小张");
p2.setAge(18);
p2.setSex("男");
p2.work();
p2.hello();
p2.show();
}
}
题目3
3./*定义Shape抽象类,包含私有属性color,创建构造器为color赋值;包含计算周长的方法celPerimeter();定义子类Triangle,包含三边;定义子类Circle,包含半径radius;子类分别实现父类的计算周长功能。*/
Shape
public abstract class Shape {
private String color;
public Shape() {
}
public Shape(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void celPerimeter(){
}
}
Circle
public class Circle extends Shape {
double radius;
public Circle() {
}
public Circle(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public void celPerimeter() {
double g = (radius + radius) * Math.PI;
// System.out.println(radius);
System.out.println(g);
}
}
Triangle
public class Triangle extends Shape{
double a;
double b;
double c;
// double f=a+b+c;
public Triangle() {
}
public Triangle(double a, double b, double c) {
this.a=a;
this.b=b;
this.c=c;
}
public double getA() {
return a;
}
public void setA(double a) {
this.a = a;
}
public double getB() {
return b;
}
public void setB(double b) {
this.b = b;
}
public double getC() {
return c;
}
public void setC(double c) {
this.c = c;
}
@Override
public void celPerimeter(){
double f=a+b+c;
System.out.println(a+ ","+b+ ","+c);
System.out.println(f);;
}
}
测试类
public class ShapeDemo {
public static void main(String[] args) {
Shape s1 = new Circle(3.0);
s1.celPerimeter();
Shape s2 = new Triangle(3.0,4.5,6.5);
s2.celPerimeter();
}
}
题目4
4.编写工资系统,实现不同类型员工(多态)的按月发放工资。如果当月出现某个
Employee对象的生日,则将该雇员的工资增加100元。
实验说明:
(1)定义一个Employee类,该类包含:
private成员变量name,number,birthday,其中birthday 为MyDate类的对象;
abstract方法earnings();
toString()方法输出对象的name,number和birthday。
(2)MyDate类包含:
private成员变量year,month,day ;
toDateString()方法返回日期对应的字符串:xxxx年xx月xx日
(3)定义SalariedEmployee类继承Employee类,实现按月计算工资的员工处
理。该类包括:private成员变量monthlySalary;
实现父类的抽象方法earnings(),该方法返回monthlySalary值;toString()方法输
出员工类型信息及员工的name,number,birthday。
(4)参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的员工处理。该类包括:
private成员变量wage和hour;
实现父类的抽象方法earnings(),该方法返回wage*hour值;
toString()方法输出员工类型信息及员工的name,number,birthday。
(5)定义PayrollSystem类,创建Employee变量数组并初始化,该数组存放各类雇员对象的引用。利用循环结构遍历数组元素,输出各个对象的类型,name,number,birthday,以及该对象生日。当键盘输入本月月份值时,如果本月是某个Employee对象的生日,还要输出增加工资信息。
/*
Employee
public abstract class Employee {
private String name;
private int number;
private MyDate birthday;
public Employee() {
}
public Employee(String name, int number, MyDate birthday) {
this.name = name;
this.number = number;
this.birthday = birthday;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public MyDate getBirthday() {
return birthday;
}
public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}
public abstract double earnings(int month);
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", number=" + number +
", birthday=" + birthday.toDateString() +
'}';
}
}
MyDate
public class MyDate {
private int year;
private int month;
private int day;
public MyDate() {
}
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public String toDateString(){
return year+"年"+month+"月"+day+"日";
}
}
SalariedEmployee
public class SalariedEmployee extends Employee {
private double monthlySalary;
MyDate m1;
public SalariedEmployee() {
}
public SalariedEmployee(double monthlySalary) {
this.monthlySalary = monthlySalary;
}
public SalariedEmployee(String name, int number, MyDate birthday, double monthlySalary) {
super(name, number, birthday);
this.monthlySalary = monthlySalary;
}
public double getMonthlySalary() {
return monthlySalary;
}
public void setMonthlySalary(double monthlySalary) {
this.monthlySalary = monthlySalary;
}
@Override
public double earnings(int month ){
if (super.getBirthday().getMonth()==month)
return monthlySalary+100;
return monthlySalary;
}
@Override
public String toString() {
return super.toString();
}
}
HourlyEmployee
public class HourlyEmployee extends Employee {
private double wage;
private double hour;
public HourlyEmployee() {
}
public HourlyEmployee(double wage, double hour) {
this.wage = wage;
this.hour = hour;
}
public HourlyEmployee(String name, int number, MyDate birthday, double wage, double hour) {
super(name, number, birthday);
this.wage = wage;
this.hour = hour;
}
@Override
public double earnings(int month) {
if (super.getBirthday().getMonth()==month)
return wage*hour+100;
return wage*hour;
}
@Override
public String toString() {
return super.toString();
}
}
测试类PayrollSystem
import java.util.Scanner;
public class PayrollSystem {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入现在的月份");
int a=sc.nextInt();
Employee h1=new HourlyEmployee("zhangsan",001,new MyDate(1999,5,25),2,1000);
Employee h2=new SalariedEmployee("lisi",002,new MyDate(1994,3,15),400);
System.out.println(h1.earnings(a));
System.out.println(h2.earnings(a));
}
}
接口
概述:接口就是一种公共的规范标准,符合规范标准都可以通用。Java中的接口更多的体现在对行为的抽象!
特点
1、接口用关键字interface修饰
public interface 接口名 {}
2、类实现接口用implements表示
public class 类名 implements 接口名 {}
3、接口不能实例化
需要实例化:参照多态的方式,通过实现类对象实例化,这叫接口多态。
多态的形式:具体类多态,抽象类多态,接口多态。
4、接口的子类(重写接口中的所有抽象方法,要么子类也是抽象类 )
成员特点
成员变量:只能是常量 默认修饰符:public static final
构造方法: 没有,因为接口主要是扩展功能的,而没有具体存在
成员方法:只能是抽象方法 默认修饰符:public abstract
类和接口的关系
1、类与类的关系
继承关系,只能单继承,但是可以多层继承
2、类与接口的关系
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
3、接口与接口的关系
继承关系,可以单继承,也可以多继承
抽象类和接口的区别
1、成员区别
抽象类:变量,常量;有构造方法;有抽象方法,也有非抽象方法
接口: 常量;抽象方法
2、关系区别
类与类:继承,单继承
类与接口: 实现,可以单实现,也可以多实现
接口与接口:继承,单继承,多继承
3、设计理念区别
抽象类:对类抽象,包括属性、行为
接口:对行为抽象,主要是行为
参数传递
类名作为形参和返回值
1、类名作为方法的形参:
方法的形参是类名,其实需要的是该类的对象,实际传递的是该对象的【地址值】
2、类名作为方法的返回值
方法的返回值是类名,其实返回的是该类的对象,实际传递的,也是该对象的【地址值】
抽象类作为形参和返回值
1、方法的形参是抽象类名,其实需要的是该抽象类的子类对象
2、方法的返回值是抽象类名,其实返回的是该抽象类的子类对象
接口名作为形参和返回值
1、方法的形参是接口名,其实需要的是该接口的实现类对象
2、方法的返回值是接口名,其实返回的是该接口的实现类对象
interface Jumpping {
void jump();
}
class JumppingOperator {
public void useJumpping(Jumpping j) { //Jumpping j = new Cat();
j.jump();
}
public Jumpping getJumpping() {
Jumpping j = new Cat();
return j;
}
}
class Cat implements Jumpping {
@Override
public void jump() {
System.out.println("猫可以跳高了");
}
}
public class JumppingDemo {
public static void main(String[] args) {
//创建操作类对象,并调用方法
JumppingOperator jo = new JumppingOperator();
Jumpping j = new Cat();
jo.useJumpping(j);
Jumpping j2 = jo.getJumpping(); //new Cat()
j2.jump();
}
}