利用继承,人们可以基与已经存在的类构造一个新类。继承已存在的类就是复用这些类的方法和域。在此基础上,还可以添加一些新的方法和域,来满足新的需求。
class A extends B{
}
A:子类、派生类、subclass
B:父类、超类、基类、superclass
子类继承了父类,就继承了父类的方法和属性。
在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和方法。
在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集, 而是对父类的“扩展”。
1.一个类可以被多个子类继承,一个类只能有一个父类。
2.子类不能直接访问父类中私有的(private)的成员变量和方法。
2.Java只支持单继承和多层继承,不允许多重继承 ,即一个子类只能有一个父类 ,一个父类可以派生出多个子类 。
3.子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
4.子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法
Person.java:
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("eating...");
}
public void sleep() {
System.out.println("sleeping...");
}
//由于name和age都有private属性修饰,因此在子类中无法直接使用
//需要get/set方法来进行调用
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;
}
}
Student.java:
public class Student extends Person {
String major;
public Student() {
}
public Student(String name, int age, String major) {
setName(name);
setAge(age);
this.major = major;
}
public void study() {
System.out.println("studing.......");
}
}
TestExtend .java:
public class TestExtend {
public static void main(String[] args) {
Person p1 = new Person("张三", 18);
p1.eat();
Student s1 = new Student("Tom", 28, "cs");
s1.eat();
s1.study();
}
}
1.如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.Object类
2. 所有的java类(除java.lang.Object类之外)都直接或间接的继承于java.lang.Object类
3. 意味着,所有的java类具有java.lang.Object类声明的功能
在子类中可以根据需要对从父类中继承来的方法进行改造,也称 为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。
子类中叫重写的方法,父类中叫被重写的方法。
1.子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
2. 子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限 。注意: 子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限
3.子类重写的方法的返回值类型不能大于父类被重写的方法的返回值类型
①父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
②父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
③父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)
4.子类方法抛出的异常不能大于父类被重写方法的异常
注意:子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为 static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。
Person.java:
public class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("eating....");
}
public void walk(int distance) {
System.out.println("wakling distance is" + distance + " !!!");
}
public Object Info() {
return null;
}
}
Student.java:
public class Student extends Person{
String major;
public Student() {
}
public Student(String major) {
this.major = major;
}
public void study() {
System.out.println("学习的专业知识为 " + major);
}
//对父类中的方法进行重写
public void eat() {
System.out.println("学生应该多吃点");
}
//引用类型的重写,可以是Object或Object的子类
public String Info() {
return null;
}
}
PersonTest.java:
public class PersonTest {
public static void main(String[] args) {
Student s = new Student("cs");
s.eat();
s.walk(100);
s.study();
Person p = new Person("Tom", 18);
p.eat();
}
}
super可用于访问父类中定义的属性
super可用于调用父类中定义的成员方法
super可用于在子类构造器中调用父类的构造器
1.我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super."
2.特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性。
3. 特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法。
Person.java:
public class Person {
String name;
int age;
int id = 2000;
public Person(){
}
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this(name);
this.age = age;
}
public void eat() {
System.out.println("人:吃饭");
}
public void walk() {
System.out.println("人:睡觉");
}
}
Student.java:
public class Student extends Person{
String major;
int id = 1000;
public Student() {
}
public Student(String major) {
this.major = major;
}
@Override
public void eat() {
System.out.println("学生:多吃点有营养的");
}
public void study() {
System.out.println("学生:学习知识");
this.eat();//调用当前类中的eat方法
super.eat();//调用父类中的eat方法
}
public void show(){
System.out.println("id = " + id);//调用当前类中的id
System.out.println("id = " + super.id);//调用父类中的id
}
}
SuperTest.java:
public class SuperTest {
public static void main(String[] args) {
Student s = new Student();
s.show();
System.out.println();
s.study();
}
}
1.我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器
2."super(形参列表)"的使用,必须声明在子类构造器的首行
3.我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)“只能二选一,不能同时出现
4. 在构造器的首行,没有显式的声明"this(形参列表)“或"super(形参列表)”,则默认调用的是父类中空参的构造器:super()
5. 在类的多个构造器中,至少有一个类的构造器中使用了"super(形参列表)”,调用父类中的构造器
Person.java:
public class Person {
String name;
int age;
int id = 2000;
public Person(){
}
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this(name);
this.age = age;
}
public void eat() {
System.out.println("人:吃饭");
}
public void walk() {
System.out.println("人:睡觉");
}
}
Studnet.java:
public class Student extends Person{
String major;
int id = 1000;
public Student() {
}
public Student(String major) {
this.major = major;
}
public Student(String name, int age, String major) {
super(name, age);
this.major = major;
}
@Override
public void eat() {
System.out.println("学生:多吃点有营养的");
}
public void study() {
System.out.println("学生:学习知识");
this.eat();//调用当前类中的eat方法
super.eat();//调用父类中的eat方法
}
public void showid(){
System.out.println("id = " + id);//调用当前类中的id
System.out.println("id = " + super.id);//调用父类中的id
}
public void show() {
System.out.println("name = "+ name + ",age = " + age);
}
}
SuperTest.java:
public class SuperTest {
public static void main(String[] args) {
Student s = new Student();
s.showid();
System.out.println();
s.study();
System.out.println();
Student s1 = new Student("tom", 21, "math");
s1.show();
}
}
1.从结果上来看:(继承性)
子类继承父类以后,就获取了父类中声明的属性或方法。
创建子类的对象,在堆空间中,就会加载所有父类中声明的属性。
2.从过程上来看:
当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器,…直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有父类中的结构,子类对象才可以考虑进行调用。
注意:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为new的子类对象
public class Person {
String name;
char sex;
int age;
public Person() {
}
public Person(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String toString() {
return "name = " + name + ", sex = " + sex + ", age = " + age ;
}
}
Student.java:
public class Student extends Person{
long number;
int math;
int english;
int computer;
public Student(String n, char s, int a, long k, int m, int e, int c ) {
this.name = n;
this.sex = s;
this.age = a;
this.number = k;
this.math = m;
this.english = e;
this.computer = c;
}
public double aver() {
return (math + english + computer) / 3.0;
}
public int max() {
int max = 0;
if(math >= english && math >= computer) {
max = math;
}
if(english >= math && english >= computer) {
max = english;
}
if(computer >= math && computer >= english) {
max = computer;
}
return max;
}
public int min() {
int min = 0;
if(math <= english && math <= computer) {
min = math;
}
if(english <= math && english <= computer) {
min = english;
}
if(computer <= math && computer <= english) {
min = computer;
}
return min;
}
public String toString() {
return "name = " + name + ", sex = " + sex + ", age = " + age
+ ", number =" + number + ", math = " + math + ", english = "
+ english + ", computer = " + computer;
}
}
Test.java:
public class Test {
public static void main(String[] args) {
Student s = new Student("wu", '男', 18, 123456, 10, 20, 30);
System.out.println("aver = " + s.aver() + ", max = " + s.max()
+ ", min = " + s.min());
System.out.println(s.toString());
}
}
public class ManKind {
private int sex;
private int salary;
public ManKind() {
}
public ManKind(int sex, int salary) {
this.sex = sex;
this.salary = salary;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public void manOrWoman() {
if(sex == 1) {
System.out.println("man");
}else if(sex == 0) {
System.out.println("woman");
}else {
System.out.println("非法值");
}
}
public void employeed() {
if(salary == 0) {
System.out.println("no job");
}else {
System.out.println("job");
}
}
}
Kids.java:
public class Kids extends ManKind {
private int yearsOld;
public Kids() {
}
public Kids(int yearsOld) {
this.yearsOld = yearsOld;
}
public int getYearsOld() {
return yearsOld;
}
public void setYearsOld(int yearsOld) {
this.yearsOld = yearsOld;
}
public void printAge() {
System.out.println("yearsOld = " + yearsOld);
}
}
KidTest.java:
public class KidTest {
public static void main(String[] args) {
Kids somekid = new Kids(15);
somekid.printAge();
somekid.setSex(1);
somekid.setSalary(0);
somekid.employeed();
somekid.manOrWoman();
}
}
public class Circle {
private double radius;
public Circle() {
radius = 1;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
public double findArea(){
return Math.PI * radius *radius;
}
}
Cylinder.java:
public class Cylinder extends Circle {
private double length;
public Cylinder() {
length = 1;
}
public void setLength(double length) {
this.length = length;
}
public double getLength() {
return length;
}
public double findVolume() {
return findArea() * length;
}
}
CylinderTest.java:
public class CylinderTest {
public static void main(String[] args) {
Cylinder c1 = new Cylinder();
c1.setRadius(1);
c1.setLength(1);
System.out.println("圆柱体积为 :" + c1.findVolume());
}
}
public class Account {
private int id;//帐号
private double balance;//余额
private double annualInterestRate;//年利率
public Account() {
}
public Account(int id, double balance, double annualInterestRate) {
this.id = id;
this.balance = balance;
this.annualInterestRate = annualInterestRate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getAnnualInterestRate() {
return annualInterestRate;
}
public void setAnnualInterestRate(double annualInterestRate) {
this.annualInterestRate = annualInterestRate;
}
public double getMonthInterest() {
return annualInterestRate/12.0;
}
//取款
public void withdraw(double amount) {
if(amount >= balance) {
System.out.println("余额不足!");
}else {
balance -= amount;
System.out.println("取款成功");
}
}
//存款
public void deposit(double amount) {
if(amount < 0) {
System.out.println("不合法 !!!!");
}else {
balance += amount;
System.out.println("存款成功!");
}
}
}
CheckAccount.java:
public class CheckAccount extends Account{
private double overdraft;
public CheckAccount() {
}
public CheckAccount(int id, double balance, double annualInterestRate, double overdraft){
super(id, balance, annualInterestRate);
this.overdraft = overdraft;
}
public double getOverdraft() {
return overdraft;
}
public void setOverdraft(double overdraft) {
this.overdraft = overdraft;
}
//可透支的取款功能
@Override
public void withdraw(double amount){
if(amount <= getBalance()) {//余额足够消费
//setBalance(getBalance() - amount);
//System.out.println("取款成功!余额为" + getBalance());
super.withdraw(amount);
}else if((getBalance() + overdraft) >= amount){ //余额透支+余额足够消费
overdraft = overdraft - (amount - getBalance());
setBalance(0);
System.out.println("透支取款成功!");
}else{//余额透支不足够消费
System.out.println("已经超出可透支额度,取款失败!!");
}
}
}
Test.java:
public class Test {
public static void main(String[] args) {
Account acc = new Account(1122, 20000, 0.045);
acc.withdraw(30000);
System.out.println("您的账户余额为:" + acc.getBalance());
acc.withdraw(2500);
System.out.println("您的账户余额为:" + acc.getBalance());
acc.deposit(3000);
System.out.println("您的账户余额为:" + acc.getBalance());
System.out.println("月利率为:" +acc.getAnnualInterestRate()*100 + "%" );
System.out.println("******************************");
CheckAccount cacc = new CheckAccount(1122, 20000, 0.045,5000);
cacc.withdraw(5000);
System.out.println("您的账户余额为:" + cacc.getBalance());
System.out.println("您的可透支额度为:" + cacc.getOverdraft());
cacc.withdraw(18000);
System.out.println("您的账户余额为:" + cacc.getBalance());
System.out.println("您的可透支额度为:" + cacc.getOverdraft());
cacc.withdraw(3000);
System.out.println("您的账户余额为:" + cacc.getBalance());
System.out.println("您的可透支额度为:" + cacc.getOverdraft());
}
}
参考资料:
[1]尚硅谷宋康红java基础教程