1.继承
继承是Java中实现代码重用的重要手段之一。Java中只支持单根继承,即一个类只能有一个直接父类。
子类与父类是 is-a 的关系,子类是父类
父子类信息编写原则:
父类中编写共有的属性和行为
子类中编写独有的属性和行为
public class Pet {
private String name;
private int health;
private int love;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public void print() {
System.out.println("宠物的名字是" + name + ",健康值是" + health + ",爱心值是" + love);
}
}
public class Dog extends Pet{
private String strain;
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
public Dog() {}
}
public class Penguin extends Pet{
private String sex;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Penguin() {}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.setName("大黄");// Pet继承而来的
dog.setHealth(100);// Pet继承而来的
dog.setLove(100); // Pet继承而来的
dog.setStrain("哈士奇"); // Dog类编写的
dog.print();
// 调用从父类继承而来的print方法打印信息 发现以下两个问题:
// 1.打印信息身份不准确
// 2.打印信息不具体
System.out.println("===============================================");
Penguin p1 = new Penguin();
p1.setName("大白");// Pet继承而来的
p1.setLove(100);// Pet继承而来的
p1.setHealth(100);// Pet继承而来的
p1.setSex("雌"); // Penguin类编写的
System.out.println(p1.getName());
System.out.println(p1.getHealth());
System.out.println(p1.getLove());
System.out.println(p1.getSex());
p1.print();
}
}
2. super关键字
super关键字指父类对象,可以访问父类权限允许的方法、属性、构造方法。
public class Pet {
protected String name;
protected int health;
protected int love;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public void print() {
System.out.println("宠物的名字是" + name + ",健康值是" + health + ",爱心值是" + love);
}
}
public class Dog extends Pet{
private String strain;
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
public Dog() {}
public void printDog() {
super.print();
System.out.println("狗狗的品种是" + strain);
}
public Dog(String name,int health,int love,String strain) {
this.strain = strain;
super.name = name;
super.health = health;
super.love = love;
}
}
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.setName("大黄");
dog.setHealth(100);
dog.setLove(100);
dog.setStrain("金毛");
// dog.print();
dog.printDog();
System.out.println("===========================");
Penguin p1 = new Penguin();
p1.setName("大白");
p1.setLove(100);
p1.setHealth(100);
p1.setSex("雌");
p1.printPenguin();
System.out.println("===========================");
Dog dog1 = new Dog("小黑", 100, 100, "金毛");
dog1.printDog();
}
}
super关键字使用构造方法创建子类对象时,默认调用父类的无参构造方法,除非子类显式的调用父类的有参构造方法
子类必须调用父类的构造方法,无参或者有参必须调用一个
public class Pet {
protected String name;
protected int health;
protected int love;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public Pet(String name,int health,int love) {
this.name = name;
this.health = health;
this.love = love;
}
/**
* 父类中推荐都提供无参 方便子类使用
*/
public Pet() {}
public void print() {
System.out.println("宠物的名字是" + name + ",健康值是" + health + ",爱心值是" + love);
}
}
/**
* 狗类
* 品种
* 打印狗狗信息
* @author WHD
*
*/
public class Dog extends Pet{
private String strain;
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
public void printDog() {
print();
System.out.println("狗狗的品种是" + strain);
}
/**
* 因为父类的无参构造被覆盖了 所以Dog子类报错
* 解决方案:编写有参构造调用父类的有参 不再调用无参
* @param name
* @param health
* @param love
* @param strain
*/
public Dog(String name,int health,int love,String strain) {
super(name, health, love);
this.strain = strain;
}
}
/**
* 企鹅类
* 性别
* 打印信息
* @author WHD
*
*/
public class Penguin extends Pet{
private String sex;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public void printPenguin() {
super.print(); // 继承自父类的方法 可以使用super加点 或者this加点 或者直接书写 方法名
System.out.println("企鹅的性别是" + sex);
}
}
3.方法重写
方法重写的要求:
1.父子类之间的
2.方法名称相同
3.参数列表相同
4.访问权限不能严于父类,不能窄化父类的访问权限
5.返回值相同或者是其子类
6.父类的静态方法可以被继承,但是不能被重写,非静态方法不能重写为静态方法
7.不能抛出比父类更多的异常
@Override注解:用于子类的方法上,表示此方法为重写父类的方法,如果没有符合以上重写的规则,那么将编译报错。
/**
* 狗类
* 品种
* 打印狗狗信息
* @author WHD
*
*/
public class Dog extends Pet{
private String strain;
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
/**
* 方法重写
* 1.父子类之间的
* 2.方法名称相同
* 3.参数列表相同
* 4.访问权限不能严于父类 不能窄化父类的访问权限
* 5.返回值相同 或者是其子类
*
* 6.父类的静态方法可以被继承 但是不能被重写 非静态方法不能重写为静态方法
* 7.不能抛出比父类更多的异常
*/
@Override
public void print() {
super.print();
System.out.println("狗狗的品种是" + strain);
}
public static void m1() {
}
public Dog(String name,int health,int love,String strain) {
super(name, health, love);
this.strain = strain;
}
}
4. Object类
Object类是所有类的父类,所有的类将默认继承自此类
此类中提供了一些常用的方法,实际开发中我们经常重写这些方法
4.1 重写toString方法
我们直接打印一个对象将默认调用此对象的toString方法,返回值为包名类名+@+哈希值
如果我们不想要这个效果,可以重写toString方法
/**
* 学生类
* 名字
* 年龄
* @author WHD
*
*/
public class Student{
private String name;
private int age;
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;
}
public String toString() {
String str = super.toString();
return "Student[name=" + name + ",age=" + age + "]" + str;
}
public static void main(String[] args) {
Student stu = new Student();
stu.setName("赵四");
stu.setAge(17);
System.out.println(stu.getName());
System.out.println(stu.getAge());
System.out.println(stu); // 直接打印一个对象将调用从父类继承而来的toString方法
System.out.println(stu.toString());
}
}