继承
this关键字
- 解决局部变量与成员变量同名之间的二义性
- 同一个类中非static方法间互调(此时可以省略this,但是不建议省略)
- 构造器重载的互调
- 主要存在于两个位置: 在构造器中–>表示当前被创建的对象; 在方法中–>哪一个对象调用this所在的方法,此时this就表示哪一个对象.
// this 关键字具体使用
public class Dog {
private String name;
private int age;
public Dog() {
// 这个必须写在构造器中的第一行
this("大白"); // 构造器重载,直接使用this互调,根据参数调用相应构造器
}
public Dog(String name) {
this(name, 10); // 构造器重载,直接使用this互调
}
public Dog(String name, int age) {
//用来解决局部变量和成员变量之间的二义性,此时必须使用,否则值传不进成员变量
this.name = name;
this.age = age;
}
public void say() {
String name = "成员变量";
System.out.println(name); // 局部变量
System.out.println(this.name); // 成员变量
// other();等价于this.other();
this.other(); // 同一个类中非static方法间互调(可以省略this,但是不建议省略)
}
private void other() {
System.out.println(this.age); // 成员变量
}
}
构造器与setter方法的选用
构造器与setter方法都可以给对象设置数据,如果在创建对象时清楚成员变量的值,那么可以使用有参构造器,反之用无参构造器先创建对象,然后在适当的时候使用setter方法来赋值.
- 构造器: 构造器在创建对象的时候设置初始数据,只能初始化一次
- setter方法: 创建对象后再设置初始数据,可以设置多次
继承思想
含义:继承是面向对象的三大特征之一,继承的基本思想是基于某个父类的扩展,并制定一个新的子类,子类可以继承父类中原有的属性和方法,也可以增加父类不具备的属性和方法,或者重写父类中的某些方法.
好处: 子类之间不会存在代码重复,维护性提高了,代码也简洁,提高代码的复用性
注意: java不支持多继承,只支持单继承,也就是说一个类只有一个直接父类,父类也可以有父类
子类可以继承父类的成员(成员变量,成员方法):
- 父类中使用public和protected修饰的成员都可以被子类继承
- 如果父类和子类在同一包中,使用缺省(没有修饰符)修饰的成员可以被子类继承
- 父类的构造器不能被子类继承,因为构造器的名字必须和类同名
方法重写(覆盖)
方法重写:
- 当父类中的方法体内容不适合子类时,子类可以继续父类的该方法,然后重新定义方法体,也就是说当子类存在与父类一模一样的方法时,子类就重写(覆盖)了父类的方法.
- 执行顺序: 通过对象调用方法时,先在子类中查找有没有对应的方法,若存在就执行子类的,若子类不存在就执行父类的,如果父类也没有,报错
- 细节: 父类使用private修饰的方法不能被重写; 实例方法签名必须相同(方法签名 = 方法名 + 参数表); 子类的返回类型是父类的返回类型,或者是其子类; 子类方法中声明抛出的异常小于或等于父类声明抛出的异常类型; 子类方法的访问权限比父类方法访问权限更大或者相等.
(就把父类需要被重写的方法复制过来,改方法体,简单明了)
super关键字:
- 在子类方法中使用,调用父类被覆盖的方法,此时必须使用super
- 在子类构造器中,调用父类构造器,此时必须使用super语句
// super关键字
// 父类
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 doWork() {
System.out.println("Person...doWork...");
}
}
// 子类
public class Student extends Person {
private String sn;
public Student(String sn) {
super(); // 隐式调用父类无参构造器,必须作为构造的第一行
this.sn = sn;
}
public Student(String name, int age, String sn) {
super(name, age); // 显示去调用父类无参构造器,必须作为构造第一行
this.sn = sn;
}
public void doWork() {
super.doWork(); // 调用父类隐藏的方法
this.doWork(); // 调用当前类的方法
System.out.println("Student...doWork...");
}
}
抽象类和抽象方法
抽象类:
- 抽象类不能用来创建对象,调用没有方法体的抽象方法没有任何意义
- 抽象类中可以有抽象方法和普通方法
- 抽象类要有子类才有意义,子类必须重写抽象类中的所有抽象方法,否则子类也得作为抽象类
抽象方法:
- 使用abstract修饰,没有方法体,留给子类去覆盖
- 抽象方法必须定义在抽象类或接口中
// 抽象类
public abstract class 类名 {
public abstract void speak(); // 抽象方法,没有方法体,留给子类去覆盖
}
// 接口
public interface 接口名 {
void speak(); // 抽象方法,没有方法体
}
Object类的常用方法
- toString方法:String toString():表示把对象中的字段信息转换为字符串格式,默认情况下打印的是对象的hashCode值,但是我们更关心对象中字段存储的数据,所以一般使用都是重写toString方法.
// 重写toString方法
// Object类中默认toString打印的是对象的地址,我们重写toString,拿字段数据
// 字段为 String name;和int age
public String toString() {
return "姓名" + name + "年龄" + age; // 拼接字符串,结果为:姓名xx年龄xx
}
- equals方法与==的区别: Object中的equals与= =意义一样,都是拿对象的地址进行比较,如果想比较其具体数据,建议重写equals方法,和toString操作相似,重写,加入自己需要实现的方法.