Javase面向对象6:抽象类、多态、native关键字、根父类

目录

1. 笔记

1.1 抽象类

1.2 多态

1.3 native关键字

1.4 根父类(Object)

2. 练习

2.1 抽象类练习

2.2 多态练习

2.3 父子类之间类型转换练习


1. 笔记

1.1 抽象类

1.抽象类☆
     前提:Animal(父类)所有的子类都对eat方法进行了重写。Animal是为子类提供服务。
         Animal类中的eat方法,大括号还有用吗?没有用了。
         将eat方法变为抽象方法
             ①使用abstract修饰符修饰方法
             ②将大括号删除,分号结尾
         将类变为抽象类
             ①使用abstract修饰符修饰类
     特点:
         ①抽象方法存在的类,必须是抽象类!
         ②子类继承抽象类时,必须实现抽类中所有的抽象方法
             重写:父类有方法体,子类覆盖父类的方法体
             实现:父类没有方法体,子类第一次指定方法体
         ③抽象类中可以由0-n个抽象方法或普通方法
         ④如果子类不能够实现抽象类中的抽象方法?
             那么子类也必须变为抽象类
         ⑤抽象类是不能够实例化对象的!
         ⑥抽象类有构造器吗?有的!
             抽象类不能够实例化对象,抽象类的使用必须是父类了!
             所以构造器就是初始化子类对象的父类空间的
     应用:一般作为模板工具类
         模板:一部分是确定的,一部分是不确定的

2.权限修饰符
             本类      本包      其他包(子类)     其他包(非子类)
 public      √         √           √                 √
 protected   √         √           √                 ×
 缺省的        √        √          ×                 ×
 private      √        ×           ×                 ×

1.2 多态

1.多态★
     面向对象的三大特性之一
     1.1定义
         是指同一行为,具有多个不同表现形式(重载和重写)
     1.2前提
         ①父子类
         ②必须有重写
         ③父类引用指向子类对象
     1.3 多态的语法
         父类引用指向子类对象
         举例:Person per1 = new Employee();
                per1.eat(); //从名义上是调用Person类的eat方法,但是实际上是员工餐
     1.4 多态的注意事项
         使用不了子类独有的内容
             因为名义上是父类类型,就只能调用到父类中存在的,如果子类有重写
             这个是可以调用到子类的方法的,如果没有重写就是父类的
             总结:多态只能调用父类的内容
         成员变量:
                 子类独有的访问不到,如果有重名属性,调用属性看类型。
     1.5 多态的用途
         ①多态数组★
         ②多态数组 -> 对象数组的升级

2. 父子类之间的类型转换
     2.1 自动转换(向上转型-多态的体现)  小-大
     2.2 强制转换(向下转型) 大-小
         因为多态,调用不到子类独有的内容!我就是想调用(很少见)
         向下转型是有风险!所以以后能少强转就少强转!
      语法:子类类型  对象名=(子类类型)父类引用;
      强转之前一定要做判断!
             instanceof  判断前面的对象是否属于后面的类型
      举例:  boolean flag = employee instanceof Employeel;

1.3 native关键字

1. native 本地的  原生的
     只能修饰方法
     追踪源码的时侯,回见到这个关键字。方法不是java实现,是c语言实现
     native修饰的方法,是可以被重写的

  1.1 不能和abstract一起使用的修饰符?
        (1)final:和final不能一起修饰方法和类
        (2)static:和static不能一起修饰方法
        (3)native:和native不能一起修饰方法  记住
        (4)private: 和private不能一起修饰方法
  1.2  static和final一起使用:
         (1)修饰方法:可以,因为都不能被重写
         (2)修饰成员变量:可以,表示静态常量
         (3)修饰代码块:不可以,final不能修饰代码块
         (4)修饰局部变量:不可以,static不能修饰局部变量
         (5)修饰内部类:可以一起修饰成员内部类,不能一起修饰局部内部类

1.4 根父类(Object)

1. Object  根父类
        默认是类的父类! 该类中所有的方法都可以被任意对象继承下去。
        根据api去学。
        构造器:
                Object();
           方法:
             ① toString();
               public String toString(){
                return   getClass().getName()+"@"+Integer.toHexString(hashCode());
                 }
             ② Class getClass(); 反射位置,会遇到次方法!
                  功能:返回对象的运行时类型(类加载的时候,会创建一个Class对象)
             ③ int hashCode();
                 将当前对象,通过哈希算法,得到一个int值
                 两对相同对象(地址一样的):经过相同的hash算法,得到的int值肯定是                 
                                             一样的。
                 两个不同的对象:经过相同的hash算法,得到int值,也有可能一样,
                                        大概率是不一样的
                 集合-->HashMap集合的时候,会遇到hashCode方法。
              ④ finalize()
                    java存在垃圾回收机制的(自动的机制)
                    java中什么样的对象,会被认为是垃圾?
                        没有引用的对象
                    java中被认为是垃圾的对象,什么时候会被来及回收机制回收?
                         不定时回收
                     垃圾对象被回收的时候,实惠默认调用该对象的finalize方法
                       目的:是让这个对象做一个临终遗言(这个方法不是回收的代码)
              ⑤ equals(Object obj)
                    判断两个对象是否一致
                    == 主要是判断两个地址是否一致
                    源码:  和==没有区别
                    public boolean equals(Object obj){
                            return(this == obj);
                       }
    2. String类的equals方法
          两个对象,this/anObject对比内容是否一致

    自我练习:
        创建两个person对象,我认为,只要name和id都一样,就是同一个人
        在Person类中,重写equals方法(对比内容,id和name)

2. 练习

2.1 抽象类练习

练习一:定义一个几何图形父类Graphic。所有几何图形都应该具备一个计算面积的方法。但是不同的几何图形计算面积的方式完全不同。

abstract class Graphic{
	public abstract double getArea();
}
class Circle extends Graphic{
	private double radius;

	public Circle(double radius) {
		super();
		this.radius = radius;
	}

	public Circle() {
		super();
	}

	public double getRadius() {
		return radius;
	}

	public void setRadius(double radius) {
		this.radius = radius;
	}

	@Override
	public double getArea() {
		return Math.PI * radius * radius;
	}
	
}
class Rectangle extends Graphic{
	private double length;
	private double width;
	public Rectangle(double length, double width) {
		super();
		this.length = length;
		this.width = width;
	}
	public Rectangle() {
		super();
	}
	public double getLength() {
		return length;
	}
	public void setLength(double length) {
		this.length = length;
	}
	public double getWidth() {
		return width;
	}
	public void setWidth(double width) {
		this.width = width;
	}
	@Override
	public double getArea() {
		return length * width;
	}
}

练习二:

1、声明抽象父类:Person,包含抽象方法: public abstract void walk(); public abstract void eat();

2、声明子类Man,继承Person 重写walk():大步流星走路 重写eat():狼吞虎咽吃饭 新增方法:public void smoke()实现为吞云吐雾

3、声明子类Woman,继承Person 重写walk():婀娜多姿走路 重写eat():细嚼慢咽吃饭 新增方法:public void buy()实现为买买买...

4、在测试类中创建子类对象,调用方法测试

public abstract class Person {
	public abstract void walk();
	public abstract void eat();
}
public class Man extends Person {

	@Override
	public void walk() {
		System.out.println("大步流星走路");
	}

	@Override
	public void eat() {
		System.out.println("狼吞虎咽吃饭");
	}

	public void smoke(){
		System.out.println("吞云吐雾");
	}
}
public class Woman extends Person {

	@Override
	public void walk() {
		System.out.println("婀娜多姿走路");
	}

	@Override
	public void eat() {
		System.out.println("细嚼慢咽吃饭");
	}
	
	public void buy(){
		System.out.println("买买买...");
	}
}
public class TestExer1 {

	public static void main(String[] args) {
		Man m = new Man();
		m.eat();
		m.walk();
		m.smoke();
		
		System.out.println("-------------------------");
		
		Woman w = new Woman();
		w.eat();
		w.walk();
		w.buy();
	}

}

2.2 多态练习

练习一:

(1)声明抽象父类Traffic,包含抽象方法public abstract void drive()

(2)声明子类Car,Bicycle等,并重写drive方法

(3)在测试类的main中创建一个数组,有各种交通工具,遍历调用drive()方法 模拟马路上跑的各种交通工具

public abstract class Traffic {
	public abstract void drive();
}
public class Car extends Traffic {
	@Override
	public void drive() {
		System.out.println("滴滴滴...");
	}
}
public class Bicycle extends Traffic {
	@Override
	public void drive() {
		System.out.println("蹬蹬蹬。。。");
	}
}
public class TestExer1 {
	public static void main(String[] args) {
		//右边这些是用匿名对象,初始化数组
		Traffic[] arr = {new Car(),new Bicycle(),new Car(),new Bicycle()};
		for (int i = 0; i < arr.length; i++) {
			arr[i].drive();
		}
	}
}

练习二:

(1)声明一个抽象父类Person类,public abstract void toilet();

(2)声明一个子类Woman类,重写方法

(3)声明一个子类Man类,重写方法

(4)在测试类中声明一个方法,

public static void goToToilet(Person p){

        p.toilet();

}

在main中,创建不同子类对象,调用goToToilet方法进行测试

public abstract class Person {
	public abstract void toilet();
}
public class Man extends Person {
	@Override
	public void toilet() {
		System.out.println("站着..");
	}
}
public class Woman extends Person {
	@Override
	public void toilet() {
		System.out.println("坐着..");
	}
}
public class TestPerson {
	public static void main(String[] args) {
		goToToilet(new Woman());//隐含了Person p = new Woman();
		goToToilet(new Man());//隐含了Person p = new Man();
	}
	
	public static void goToToilet(Person p){
		p.toilet();
	}
}

练习三:

1、声明一个父类Employee员工类型,有属性,姓名(String) 有方法,public abstract double earning() 用于返回实发工资 public String getInfo():显示姓名和实发工资

2、声明一个子类SalaryEmployee正式工,继承父类Employee,增加属性,薪资,工作日天数,请假天数 重写方法,public double earning()返回实发工资,实发工资 = 薪资 - 薪资/工作日天数 * 请假天数,

3、声明一个子类HourEmployee小时工,继承父类Employee 有属性,工作小时数,每小时多少钱 重写方法,public double earning()返回实发工资, 实发工资 = 每小时多少钱 * 小时数

4、声明一个子类Manager经理,继承SalaryEmployee,增加属性:奖金比例 重写方法,public double earning()返回实发工资,实发工资 = (薪资 - 薪资/工作日天数 * 请假天数)*(1+奖金比例)

5、你现在是财务,需要查看每个人的实发工资,并查看工资总额。 声明一个员工数组,存储各种员工,并遍历显示他们的姓名和实发工资,并计算工资总额

public abstract class Employee {
	private String name;

	public Employee(String name) {
		super();
		this.name = name;
	}

	public Employee() {
		super();
	}

	public String getName() {
		return name;
	}

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

	public abstract double earning();

	public String getInfo() {
		return "姓名:" + name + ",实发工资:" + earning();
	}
}
public class SalaryEmployee extends Employee {
	private double salary;
	private int workingDays;//工作日天数,
	private double offDays;//请假天数

	public SalaryEmployee() {
		super();
	}

	public SalaryEmployee(String name,  double salary, int workingDays, double offDays) {
		super(name);
		this.salary = salary;
		this.workingDays = workingDays;
		this.offDays = offDays;
	}

	public double getSalary() {
		return salary;
	}

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

	public int getWorkingDays() {
		return workingDays;
	}

	public void setWorkingDays(int workingDays) {
		this.workingDays = workingDays;
	}

	public double getOffDays() {
		return offDays;
	}

	public void setOffDays(double offDays) {
		this.offDays = offDays;
	}

	/*
	 * 重写方法,public double earning()返回实发工资, 
		实发工资 = 薪资 - 薪资/工作日天数 * 请假天数
	 */
	@Override
	public double earning() {
		return salary - salary/workingDays * offDays;
	}

}
public class HourEmployee extends Employee {
	private double moneyPerHour;
	private double hours;
	
	public HourEmployee() {
		super();
	}

	public HourEmployee(String name, double moneyPerHour, double hours) {
		super(name);
		this.moneyPerHour = moneyPerHour;
		this.hours = hours;
	}

	public double getMoneyPerHour() {
		return moneyPerHour;
	}

	public void setMoneyPerHour(double moneyPerHour) {
		this.moneyPerHour = moneyPerHour;
	}

	public double getHours() {
		return hours;
	}

	public void setHours(double hours) {
		this.hours = hours;
	}

	/*
	 * 重写方法,public double earning()返回实发工资, 
		实发工资 = 每小时多少钱 * 小时数	
	 */
	@Override
	public double earning() {
		return moneyPerHour * hours;
	}

}
public class Manager extends SalaryEmployee {
	private double commisionPer;

	public Manager() {
		super();
	}

	public Manager(String name,  double salary, int workingDays, double offDays, double commisionPer) {
		super(name, salary, workingDays, offDays);
		this.commisionPer = commisionPer;
	}

	public double getCommisionPer() {
		return commisionPer;
	}

	public void setCommisionPer(double commisionPer) {
		this.commisionPer = commisionPer;
	}

	@Override
	public double earning() {
		return super.earning() * (1+commisionPer);
	}
}
public class TestEmployee {
	public static void main(String[] args) {
		Employee[] all = new Employee[3];
		
		all[0] = new HourEmployee("张三", 50, 50);
		all[1] = new SalaryEmployee("李四", 10000, 22, 1);
		all[2] = new Manager("老王", 20000, 22, 0, 0.3);
		
		double sum = 0;
		for (int i = 0; i < all.length; i++) {
			System.out.println(all[i].getInfo());
			sum += all[i].earning();
		}
		System.out.println("总额:" + sum);
	}
}

2.3 父子类之间类型转换练习

练习一:

1、声明一个父类Employee员工类型, 有属性,姓名(String),出生日期(MyDate类型,也是自定义的含年,月,日属性日期类型) 有方法,public abstract double earning() public String getInfo():显示姓名和实发工资

2、声明一个子类SalaryEmployee正式工,继承父类Employee 增加属性,薪资,工作日天数,请假天数 重写方法,public double earning()返回实发工资, 实发工资 = 薪资 - 薪资/工作日天数 * 请假天数, 重写方法,public String getInfo():显示姓名和实发工资,月薪,工作日天数,请假天数

3、声明一个子类HourEmployee小时工,继承父类Employee 有属性,工作小时数,每小时多少钱 重写方法,public double earning()返回实发工资, 实发工资 = 每小时多少钱 * 小时数 重写方法,public String getInfo():显示姓名和实发工资,时薪,工作小时数 增加方法,public void leave():打印查看使用工具是否损坏,需要赔偿

4、声明一个子类Manager经理,继承SalaryEmployee 增加属性:奖金,奖金比例 重写方法,public double earning()返回实发工资, 实发工资 = (薪资 - 薪资/工作日天数 * 请假天数)*(1+奖金比例) 重写方法,public String getInfo():显示姓名和实发工资,月薪,工作日天数,请假天数,奖金比例

5、声明一个员工数组,存储各种员工, 你现在是人事,从键盘输入当前的月份,需要查看每个人的详细信息。 如果他是正式工(包括SalaryEmployee和Manager),并且是本月生日的,祝福生日快乐,通知领取生日礼物。如果是HourEmployee显示小时工,就进行完工检查,即调用leave方法

public abstract class Employee {
	private String name;
	private MyDate birthday;
	public Employee(String name, MyDate birthday) {
		super();
		this.name = name;
		this.birthday = birthday;
	}
	public Employee(String name, int year, int month, int day) {
		super();
		this.name = name;
		this.birthday = new MyDate(year, month, day);
	}
	public Employee() {
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public MyDate getBirthday() {
		return birthday;
	}
	public void setBirthday(MyDate birthday) {
		this.birthday = birthday;
	}
	
	public abstract double earning();
	
	public String getInfo(){
		return "姓名:" + name + ",生日:" + birthday.getInfo() +",实发工资:" + earning();
	}
}
public class SalaryEmployee extends Employee {
	private double salary;
	private int workingDays;//工作日天数,
	private double offDays;//请假天数

	public SalaryEmployee() {
		super();
	}

	public SalaryEmployee(String name, int year, int month, int day, double salary, int workingDays, double offDays) {
		super(name, year, month, day);
		this.salary = salary;
		this.workingDays = workingDays;
		this.offDays = offDays;
	}

	public SalaryEmployee(String name, MyDate birthday, double salary, int workingDays, double offDays) {
		super(name, birthday);
		this.salary = salary;
		this.workingDays = workingDays;
		this.offDays = offDays;
	}

	public double getSalary() {
		return salary;
	}

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

	public int getWorkingDays() {
		return workingDays;
	}

	public void setWorkingDays(int workingDays) {
		this.workingDays = workingDays;
	}

	public double getOffDays() {
		return offDays;
	}

	public void setOffDays(double offDays) {
		this.offDays = offDays;
	}

	/*
	 * 重写方法,public double earning()返回实发工资, 
		实发工资 = 薪资 - 薪资/工作日天数 * 请假天数
	 */
	@Override
	public double earning() {
		return salary - salary/workingDays * offDays;
	}
	
	@Override
	public String getInfo() {
		return super.getInfo() + ",月薪:" + salary + ",工作日:" + workingDays +",请假天数:" + offDays;
	}
}
public class HourEmployee extends Employee {
	private double moneyPerHour;
	private double hours;
	
	public HourEmployee() {
		super();
	}

	public HourEmployee(String name, int year, int month, int day, double moneyPerHour, double hours) {
		super(name, year, month, day);
		this.moneyPerHour = moneyPerHour;
		this.hours = hours;
	}

	public HourEmployee(String name, MyDate birthday, double moneyPerHour, double hours) {
		super(name, birthday);
		this.moneyPerHour = moneyPerHour;
		this.hours = hours;
	}

	public double getMoneyPerHour() {
		return moneyPerHour;
	}

	public void setMoneyPerHour(double moneyPerHour) {
		this.moneyPerHour = moneyPerHour;
	}

	public double getHours() {
		return hours;
	}

	public void setHours(double hours) {
		this.hours = hours;
	}

	/*
	 * 重写方法,public double earning()返回实发工资, 
		实发工资 = 每小时多少钱 * 小时数	
	 */
	@Override
	public double earning() {
		return moneyPerHour * hours;
	}

	@Override
	public String getInfo() {
		return super.getInfo() + ",时薪:" + moneyPerHour + ",小时数:" + hours;
	}

	public void leave(){
		System.out.println("小时工,查看使用工具是否损坏,需要赔偿,然后拿钱走人");
	}
}
public class Manager extends SalaryEmployee {
	private double commisionPer;

	public Manager() {
		super();
	}

	public Manager(String name, int year, int month, int day, double salary, int workingDays, double offDays,
			double commisionPer) {
		super(name, year, month, day, salary, workingDays, offDays);
		this.commisionPer = commisionPer;
	}

	public Manager(String name, MyDate birthday, double salary, int workingDays, double offDays, double commisionPer) {
		super(name, birthday, salary, workingDays, offDays);
		this.commisionPer = commisionPer;
	}

	public double getCommisionPer() {
		return commisionPer;
	}

	public void setCommisionPer(double commisionPer) {
		this.commisionPer = commisionPer;
	}

	@Override
	public double earning() {
		return super.earning() * (1+commisionPer);
	}
	@Override
	public String getInfo() {
		return super.getInfo() + ",奖金比例:" + commisionPer;
	}
}
public class TestEmployee {
	public static void main(String[] args) {
		Employee[] all = new Employee[3];
		/*all[0] = new HourEmployee("张三", new MyDate(1990, 5, 1), 50, 50);
		all[1] = new SalaryEmployee("李四", new MyDate(1991, 1, 1), 10000, 22, 1);
		all[2] = new Manager("老王", new MyDate(1987, 12, 8), 20000, 22, 0, 0.3);*/
		
		all[0] = new HourEmployee("张三", 1990, 5, 1, 50, 50);
		all[1] = new SalaryEmployee("李四", 1991, 1, 1, 10000, 22, 1);
		all[2] = new Manager("老王", 1987, 12, 8, 20000, 22, 0, 0.3);
		
		//从键盘输入当前的月份
		Scanner input = new Scanner(System.in);
		System.out.print("请输入当前月份:");
		int month;
		while(true){
			month = input.nextInt();
			if(month>=1 && month<=12){
				break;
			}
		}
		input.close();
		
		for (int i = 0; i < all.length; i++) {
			System.out.println(all[i].getInfo());
			if(all[i] instanceof SalaryEmployee){
				if(month == all[i].getBirthday().getMonth()){
					System.out.println(all[i].getName() +"生日快乐,领取生日补助购物卡");
				}
			}else{
				HourEmployee he = (HourEmployee) all[i];
				he.leave();
			}
		}
	}
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯丰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值