皮皮安学习Java第六天"/>
皮皮安学习Java第六天
写在前面
终于,终于来了,面向对象的特征:继承,封装,多态。按常理写在前面应该先水两句的,太激动了,太激动了,抱歉。先水两句吧。
大家是不是还沉溺在昨天的520?我还沉溺在IDEA的bug中,www,今天单代码就敲了按小时计数了,特别是bug,看不懂,还好IDEA强大,这要换着eclipse可能就不会在十点之前写总结了。这段时间一直学Java去了,我开始慌小程序那边...怎么办,还啥都不会...不管了,不管了,先把这三大金刚学完在说,明天周五,课比较少,加上周末,应该可以解决...
说好的的先水的,,,说着说着又说到程序上面来了,最近喜欢上神探夏洛特,放心,这一节会非常非常用心,写到这已经前前后后大概三个小时了,好了好了,不水了,今晚早点睡。
今日所学
先放源码
import java.time.LocalDate;public class Employee{private String name;private double salary;private LocalDate hireDate;public Employee(String name,double salary,int year,int month,int day){this.name = name;this.salary = salary;hireDate = LocalDate.of(year,month,day);}public String getName(){return name;}public double getSalary(){return salary;}public LocalDate getHireDate(){return hireDate;}public void raiseSalary(double byPercent){double raise = salary * byPercent / 100;salary += raise;} }
public class Manager extends Employee{private double bonus;public Manager(String name,double salary,int year,int month,int day){super(name,salary,year,month,day);bonus = 0;}public double getBonus(){double baseSalary = super.getSalary();return baseSalary + bonus;}public void setBonus(double b){bonus = b;} }
public class managerTest {public static void main(String[] args) {var boss = new Manager("Pipian",80000,2001,5,22);boss.setBonus(5000);var staff = new Employee[3];staff[0] = boss;staff[1] = new Employee("huang",5000,2001,3,4);staff[2] = new Employee("wang",5000,2001,5,6);for (Employee e:staff) {System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());}} }
1.定义子类
可以如下继承Employee类来定义Manager类,这里使用关键字extends表示继承。extends表明正在构造的新类派生于一个已经存在的类。这个已经存在的类称为超类(基类,父类);新类称为子类(派生类,孩子类)
在Manager类中,增加一个用于存储奖金的字段,以及一个用于设置这个字段的新方法:
public class Manager extends Employee{private double bonus;...public void setBonus(double b){bonus = b;} }
2.覆盖方法
超类中的有些方法对子类Manager并不一定适用。具体来说,Manager类中的getSalary方法应该返回薪水和奖金的总和。所以,需要提供一个新的方法来覆盖超类中的这个方法:
public class Manager extends Empioyee
{
...
public double getSalary()
{
...
}
...
}
如何实现这个方法呢?看下面:
public double getSaray()
{
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
我们希望调用超类Employee类中的getSarlary方法,而不是目前的这个方法,所以我们要用到super关键字。
3.子类构造器
先来一个构造器:
public Employee(String name,double salary,int year,int month,int day) {super(name,salary,year,month,day);bonus = 0; }
由于Manager类的构造器不能访问Employee类的私有字段,所以必须通过一个构造器来初始化这些私有字段。使用super调用构造器的语句必须是子类构造器的第一条语句。
一个对象变量可以指示多种实际类型的现象称为多态。在运行的时候能够自动地选择适当的方法,称为动态绑定。(具体后面在总结)
4.多态
在Java程序设计语言中,对象变量是多态的。一个Employee类型的变量既可以引用一个Employee类型的对象,也可以引用Employee类的任何一个子类对象。
不过,不能将超类的引用赋给子类变量:
Manger m = staff[i] //ERROR
5.抽象类
如果自下而上在类的继承层次结构中上移,位于上层的类更具有一般性,可能更加抽象。从某种角度看,祖先类更具有一般性,人们只将它作为派生其他类的基类,而不是用来构造你想象的特定的实例。
public abstract class Person
{
...
public abstract String getDescription();
}
为了提高程序的清晰度,包含一个或者多个抽象方法的类本身必须被声明为抽象的。
最后来学生类的源码
public abstract class Person {public abstract String getDescription();private String name;public Person(String name) {this.name = name;}public String getName() {return name;} }
import java.time.LocalDate;class Employee extends Person {private double salary;private LocalDate hireDay;public Employee(String name,double salary,int year,int month,int day){super(name);this.salary = salary;hireDay = LocalDate.of(year,month,day);}public double getSalary(){return salary;}public LocalDate getHireDay(){return hireDay;}@Overridepublic String getDescription(){return String.format("an employee with a salary of $%.2f",salary);}public void raiseSalary(double byPercent){double raise = salary + byPercent / 100;salary += raise;} }
public class Student extends Person {private String major;public Student(String name,String major){super(name);this.major = major;}@Overridepublic String getDescription() {return "a student majoring in" + major;} }
public class PersonTest {public static void main(String[] args) {var people = new Person[2];people[0] = new Employee("huang",5000,1999,5,3);people[1] = new Student("pipian","computer science");for (Person p:people) {System.out.println(p.getName()+","+p.getDescription());}} }
更多推荐
皮皮安学习Java第六天
发布评论