1. 类的继承
当一个类A继承了一个已存在的类B后,类A就用于了类B所有的非private的属性和方法,但同时类A还可以根据需要,添加新的方法和属性。
在Java语言中,一个类可以拥有多个子类,但是一个子类只能拥有一个父类。
class 子类名 extends 父类名
{}
public class ExtendsDemo1 { Employee e; Manager m; public ExtendsDemo1() { e=new Employee("Wnag Xiao Yue", 3000.00, "2005/05/20"); System.out.println("Name: "+ e.getName() + "; Salary: "+ e.getSalary()+ "; Hireday: "+e.getHireDay()+"/n"); m=new Manager("Zhao XS", 8000.00, "2004/6/2", 4000.00, 20); System.out.println("Name: "+ m.getName() + "; Salary: "+ m.getSalary()+ "; Hireday: "+m.getHireDay() + "; Bonus: "+m.getBonus()+"; Holidays: "+m.getHolidays()); } public static void main(String[] args) { new ExtendsDemo1(); } } class Employee{ String name; double salary; String hireDay; public Employee(String name, double salary, String hireDay) { this.name=name; this.salary=salary; this.hireDay=hireDay; System.out.println("I'm Employee"); } public String getName() { return name; } public String getHireDay() { return hireDay; } public double getSalary() { return salary; } } class Manager extends Employee{ private double bonus; private int holidays; public Manager(String name, double salary, String hireDay, double bonus, int holidays) { super(name, salary, hireDay); //调用父类构造方法 this.bonus=bonus; this.holidays=holidays; System.out.println("I'm Manager"); } public double getBonus() { return bonus; } public int getHolidays() { return holidays; } }
I'm EmployeeName: Wnag Xiao Yue; Salary: 3000.0; Hireday: 2005/05/20
I'm Employee
I'm Manager
Name: Zhao XS; Salary: 8000.0; Hireday: 2004/6/2; Bonus: 4000.0; Holidays: 20
覆盖父类中的方法(重载:方法名、参数、返回值均不变, 只有方法体发生了变化):
public class ExtendsDemo1 { Employee e; Manager m; public ExtendsDemo1() { e=new Employee("Wnag Xiao Yue", 3000.00, "2005/05/20"); e.getInfo(); System.out.println("Name: "+ e.getName() + "; Salary: "+ e.getSalary()+ "; Hireday: "+e.getHireDay()+"/n"); m=new Manager("Zhao XS", 8000.00, "2004/6/2", 4000.00, 20); m.getInfo(); System.out.println(m.getSalary()); System.out.println("Name: "+ m.getName() + "; Hireday: "+m.getHireDay() + "; Bonus: "+m.getBonus()+"; Holidays: "+m.getHolidays()); } public static void main(String[] args) { new ExtendsDemo1(); } } class Employee{ String name; double salary; String hireDay; public Employee(String name, double salary, String hireDay) { this.name=name; this.salary=salary; this.hireDay=hireDay; } public void getInfo() { System.out.println("I'm Eployee"); } public String getName() { return name; } public String getHireDay() { return hireDay; } public double getSalary() { return salary; } } class Manager extends Employee{ private double bonus; private int holidays; public Manager(String name, double salary, String hireDay, double bonus, int holidays) { super(name, salary, hireDay); //调用父类构造方法 this.bonus=bonus; this.holidays=holidays; } public void getInfo() { System.out.println("I'm Manager"); } public double getSalary() { System.out.print("Manager Salary is: "); return salary; } public double getBonus() { return bonus; } public int getHolidays() { return holidays; } }
I'm EployeeName: Wnag Xiao Yue; Salary: 3000.0; Hireday: 2005/05/20
I'm Manager
Manager Salary is: 8000.0
Name: Zhao XS; Hireday: 2004/6/2; Bonus: 4000.0; Holidays: 20
this关键字就好像创建一个虚拟的类对象实例,在定义类的时候,就提前使用其对象实例。
注意:由于this是指向当前类实例的一个引用,因此只能在实例方法的定义中使用。而在类方法(static型静态方法)中,不能使用this关键字。
public class ThisDemo { private String name; public ThisDemo(String name) { this.name=name; } public String getName() { return name; } public void show() { String str=this.getName(); System.out.println(str); } public Object getObject() { return this; } }
子类继承父类后,若要在子类中直接调用父类的构造方法,就必须使用super(...)语句,注意一下两点:
2. 抽象类与接口
abstract关键字是抽象修饰符,只能用于修饰类和方法。
归纳总结后,使用抽象类和抽象方法要注意一下4点:
public class AbstractDemo { Employee1 e; public AbstractDemo() { e=new Employee1("Wnag Xiao Yue", 3000.00, "2005/05/20", 24); e.getInfo(); System.out.println("Age: "+e.getAge()); System.out.println("Name: "+ e.getName() + "; Salary: "+ e.getSalary()+ "; Hireday: "+e.getHireDay()+"/n"); } public static void main(String[] args) { new AbstractDemo(); } } abstract class People{ String name; int age; abstract String getName(); abstract int getAge(); } class Employee1 extends People{ double salary; String hireDay; public Employee1(String name, double salary, String hireDay, int age) { this.name=name; this.salary=salary; this.hireDay=hireDay; this.age=age; } public void getInfo() { System.out.println("I'm Eployee"); } public String getName() { return name; } public int getAge() { return age; } public String getHireDay() { return hireDay; } public double getSalary() { return salary; } }
I'm Eployee
Age: 24
Name: Wnag Xiao Yue; Salary: 3000.0; Hireday: 2005/05/20
Java语言中的接口不同于一般的类,通常称为接口类,是用来描述类的功能的。在接口类中,定义了抽象的方法和常量,形成一个属性集合,该属性集合代表了一组功能的实现。在Java语言中,一个类只能继承自一个父类;但是一个类可以实现多个接口,因此使用接口主要是为了实现类的多重继承功能。
[public] interface 接口名 [extends 父类接口]
{
//借口体
//常量声明
[public] [static] [final] 常量类型 常量名 = 常量值;
//抽象方法声明
[public] [abstract] 返回类型 方法名(参数列表) [throw 异常列表]
}
在定义接口类的时候需要注意一下几点:
public interface IEmployee { public static final double prize=1000.00; public abstract void addSalary(); }
在定义好接口后,就可以创建一个类来实现该接口类,同时在实现类中,完成接口类中抽象方法的定义。
public class UseIEmployee { Employee2 e; public UseIEmployee() { e=new Employee2("Wnag Xiao Yue", 3000.00, "2005/05/20"); e.addSalary(2); e.getInfo(); System.out.println("Name: "+ e.getName() + "; Salary: "+ e.getSalary()+ "; Hireday: "+e.getHireDay()+"/n"); } public static void main(String[] args) { new UseIEmployee(); } } class Employee2 implements IEmplyee1{ private String name; private double salary; private String hireDay; public Employee2(String name, double salary, String hireDay) { this.name=name; this.salary=salary; this.hireDay=hireDay; } public String getName() {return name;} public void getInfo() {System.out.println("I'm Employee");} public double getSalary() {return salary;} public String getHireDay() { return hireDay; } public void addSalary(int n) { salary+=prize*n; } } interface IEmplyee1 { public static final double prize = 1000.00; public abstract void addSalary(int n); }
I'm EmployeeName: Wnag Xiao Yue; Salary: 5000.0; Hireday: 2005/05/20
3. 内部类和匿名类
内部类就是定义在其他类内部的类,而内部类所在的类一般称为外部类。根据内部类在外部类中所处的位置,一般又分为定义在方法体的内部类以及定义在方法体外的成员内部类。同时,定义在方法体内的内部类又可以分为两种,分别是有实例名称的内部类和无实例名称的匿名内部类。
(1)对于定义在方法体外的内部类(成员内部类)
又可以分为以下两种情况:
new 外部类构造方法().内部类构造方法();
外部类对象实例.new 内部类构造方法();
public class InnerClassDemo1 { private String s="World"; class InnerClass{ public InnerClass() { System.out.println("This is Inner Class constructor"); } //内部类对象能够访问其所在外部类的全部属性,包括私有属性 public void showMessage(String str) { System.out.println("Hello "+s+","+str); } } public static void main(String[] args) { InnerClass i1=new InnerClassDemo1().new InnerClass(); i1.showMessage("Lilian"); System.out.println(); InnerClassDemo1 demo=new InnerClassDemo1(); InnerClass i2=demo.new InnerClass(); i2.showMessage("Kira"); } }
This is Inner Class constructorHello World,Lilian
This is Inner Class constructorHello World,Kira
new 外部类名.内部构造方法();
public class InnerClassDemo2 { private static String s= "World"; static class InnerClass{ public InnerClass() { System.out.println("This is inner class constructor"); } public void showMessage(String str) { System.out.println("Hello "+ s +","+str); } } public static void main(String[] args) { InnerClass i=new InnerClassDemo2.InnerClass(); i.showMessage("Lilian"); } }
This is inner class constructorHello World,Lilian
(2)对于定义在方法体内的内部类
由于附属于方法体,所以只能在方法体中创建对象实例,并且创建的实例也只能在方法体中被访问。所创建的对象实例的生命周期与方法体相同,当方法结束后,对象也就随之消失。
public class InnerClassDemo3 { private String str="World"; public InnerClassDemo3() { showMessage(); } public void showMessage() { System.out.println("Now you are in method!"); class InnerClass{ public InnerClass() { System.out.println("This is inner class constructor"); } public void showMesage() { System.out.println("Hello "+ str+"!"); } } InnerClass i=new InnerClass(); i.showMesage(); System.out.println("Method end!"); } public static void main(String[] args) { new InnerClassDemo3(); } }
Now you are in method!
This is inner class constructor
Hello World!
Method end!
在创建类的对象的时候,会有两种方式,第一种方式是创建对象后,将该对象保存在一个对象变量中,如下所示。
类名 对象名 = new 类构造方法();
另一种方式就是所谓的匿名类方式创建对象。使用匿名类方式创建对象时,并不将创建的对象保存在对象变量中,程序会根据创建对象的构造方法中的操作,来运行程序,当程序运行结束后,该对象的生命周期也就结束了。
new 类构造方法();
实战练习:
简单模拟一个雇员工资管理的程序系统。整个系统由5个源文件组成:
public interface IEmployee { public static final double prize=1000.00; public abstract void addSalary(); }
abstract class People { String name; int age; abstract String getName(); abstract int getAge(); }
public class Employee extends People implements IEmployee{ double salary; String hireDay; public Employee(String name, double salary, String hireDay, int age) { this.name=name; this.salary=salary; this.hireDay=hireDay; this.age=age; } public void getInfo() { System.out.println("I'm Employee"); } public double getSalary() { return salary; } public String getHireDay() { return hireDay; } //实现父类中的方法 public String getName() {return name;} public int getAge() {return age;} //实现接口中的方法 public void addSalary() { salary+=prize; } }
public class Manager extends Employee{ private double bonus; private int holidays; public Manager(String name, double salary, String hireDay, int age, int holidays) { super(name, salary, hireDay, age); this.holidays=holidays; } public void getInfo() { System.out.println("I'm Manager"); } public double getSalary() { return salary; } public int getHolidays() {return holidays;} public void addSalary() { salary+=prize*2; } }
public class ManageEmployeeSalary { Employee e1, e2; Manager m; public ManageEmployeeSalary() { e1=new Employee("Wang Xiao Yue", 3000.00, "2005/05/20", 24); e2=new Employee("Xu Guang Yang", 2000.00, "2006/06/02", 22); m=new Manager("Zhao XS", 8000.00, "2004/6/2", 26, 20); System.out.println("name:"+e1.getName()); e1.getInfo(); System.out.println("Age:"+e1.getAge()); System.out.println("Salary:"+e1.getSalary()); System.out.println("Hireday:"+e1.getHireDay()+"/n"); System.out.println("name:"+e2.getName()); e2.getInfo(); System.out.println("Age:"+e2.getAge()); System.out.println("Salary:"+e2.getSalary()); System.out.println("Hireday:"+e2.getHireDay()+"/n"); System.out.println("name:"+m.getName()); m.getInfo(); System.out.println("Age:"+m.getAge()); System.out.println("Salary:"+m.getSalary()); System.out.println("Hireday:"+m.getHireDay()+"/n"); e1.addSalary(); e2.addSalary(); m.addSalary(); System.out.println("/nAfter adding salary:"); System.out.println(e1.getName()+"'s salary is:"+e1.getSalary()); System.out.println(e2.getName()+"'s salary is:"+e2.getSalary()); System.out.println(m.getName()+"'s salary is:"+m.getSalary()); } public static void main(String[] args) { new ManageEmployeeSalary(); } }
name:Wang Xiao Yue
I'm Employee
Age:24
Salary:3000.0
Hireday:2005/05/20
name:Xu Guang Yang
I'm Employee
Age:22
Salary:2000.0
Hireday:2006/06/02
name:Zhao XS
I'm Manager
Age:26
Salary:8000.0
Hireday:2004/6/2
After adding salary:
Wang Xiao Yue's salary is:4000.0
Xu Guang Yang's salary is:3000.0
Zhao XS's salary is:10000.0