java关键字abstract之抽象类抽象方法
目录
一:abstract:抽象的
二:abstract可以用来修饰的结构:类、方法
三:abstract修饰类:抽象类
抽象类概述:
在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。
在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。
1. 抽象类不能实例化。
2. 抽象类中一定有构造器,便于子类实例化时调用(super()等,涉及子类对象的实例化全过程)
3. 开发中,都会提供类的子类,让子类对象实例化,完成相关的操作。
四:abstract修饰方法:抽象方法
1.抽象方法只有方法的声明,没有方法体。
2.包含抽象方法的类,一定是个抽象类。(抽象方法没有方法体,没有任何意义,为了保证抽象方法不让对象去调用,不让去new对象,那么就将类设计成抽象类,抽象类不能实例化对象的。)
3.反之,抽象类中可以没有抽象方法的。(只是表示此类不想造对象了。或者不让此类造对象了,还可以给子类继承用的)
4.若子类重写了父类中所有的抽象方法后,此子类方可实例化。若子类没有重写父类中的所有抽象方法,则此子类也是一个抽象类,需要abstract修饰。
五:abstract使用的注意点:
静态方法是随着类的加载而加载的,只有一份,被所有对象所共享。
1.abstract不能用来修饰:属性、构造器等结构。
2.abstract不能用来修饰私有方法,静态方法,final的方法、final的类。
解释上一条:
(abstract修饰的方法一定是在abstract类中,则此抽象类不能自己造对象,则通过继承来造对象调方法,需要子类重写方法来调用。但是private 修饰的方法,因为是私有方法不能被子类访问, 所以不能重写。互相矛盾)
(在Java中静态方法可以被继承,但是不能被覆盖,即不能重写。但是abstract方法又需要被重写,互相矛盾。)
六:抽象类的案例:
代码演示:
Employee 类:
package com.fan.domain1;
public abstract class Employee {
private String name;
private long number;
private MyDate birthday;
//无参构造
public Employee(){
super();//调用Objectde的无参构造,构造子类之前先构造父类
}
//全参构造
public Employee(String name, long 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 long getNumber() {
return number;
}
public void setNumber(long number) {
this.number = number;
}
public MyDate getBirthday() {
return birthday;
}
public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}
//抽象方法
public abstract double earnings();
@Override
public String toString() {
return
"name='" + name +
", number=" + number +
", birthday=" + birthday.toDateString()//注意这里调用的普通的输出方法。
;
}
}
MyDate 类:
package com.fan.domain1;
public class MyDate {
private int year;
private int month;
private int day;
public MyDate(){
super();//调用Objectde的无参构造,构造子类之前先构造父类
}
//全参构造
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;
}
//注意此方法返回值是String类型
public String toDateString(){
return year + "年" + month + "月" + day+"日";
}
}
SalariedEmployee 类:
package com.fan.domain1;
public class SalariedEmployee extends Employee {
private double monthSalary;//月工资
//无参构造
public SalariedEmployee() {
super();//调用父类无参构造,初始化子类对象
}
//全参构造
public SalariedEmployee(String name, long number, MyDate birthday, double monthSalary) {
super(name, number, birthday);//调用父类构造复用。
this.monthSalary = monthSalary;
}
public double getMonthSalary() {
return monthSalary;
}
public void setMonthSalary(double monthSalary) {
this.monthSalary = monthSalary;
}
@Override
public double earnings() {
return monthSalary;
}
@Override
public String toString() {
return "SalariedEmployee{" +super.toString()+//调用父类的toString方法,来实现复用
",monthSalary=" + monthSalary +
'}';
}
}
HourlyEmployee 类:
package com.fan.domain1;
public class HourlyEmployee extends Employee{
private double wage;
private double hour;
public HourlyEmployee(){
super();
}
public HourlyEmployee(String name,long number,MyDate birthday,double wage,double hour){
super(name,number,birthday);
this.wage = wage;
this.hour = hour;
}
public double getWage() {
return wage;
}
public void setWage(double wage) {
this.wage = wage;
}
public double getHour() {
return hour;
}
public void setHour(double hour) {
this.hour = hour;
}
//子类重写父类的抽象方法
@Override
public double earnings() {
return wage * hour * 240;
}
@Override
public String toString() {
return "HourlyEmployee{" +super.toString()+
'}';
}
}
PayrollSystem 类:
package com.fan.domain1;
import java.util.Calendar;
public class PayrollSystem {
public static void main(String[] args) {
Employee[] emps = new Employee[2];
emps[0] = new SalariedEmployee("张三",1001,
new MyDate(1990,01,07),12000);
emps[1] = new HourlyEmployee("李四",1002,
new MyDate(1992,06,06),60,100);
Calendar calendar = Calendar.getInstance();//获取日期实例
int month = calendar.get(Calendar.MONDAY);
System.out.println(month);
//遍历员工信息
for (int i = 0; i < emps.length; i++) {
System.out.println(emps[i]);
if(month+1 == emps[i].getBirthday().getMonth()){
System.out.println("生日快乐,奖励100元");
//这里可以向下转型设置工资
if(emps[i] instanceof SalariedEmployee){
SalariedEmployee sale =(SalariedEmployee)emps[i];
sale.setMonthSalary(sale.getMonthSalary() + 100);
System.out.println("最终工资为:" + sale.getMonthSalary());
}else if(emps[i] instanceof HourlyEmployee){
HourlyEmployee hour = (HourlyEmployee)emps[i];
double yuegongzi = hour.earnings()+100;
System.out.println("月工资为" + yuegongzi);
}
}
}
}
}
本文地址:https://blog.csdn.net/weixin_38568503/article/details/112229209
上一篇: 一段有意思的fork()程序
下一篇: python 实现redis订阅发布功能