1、方法重写的规则
方法名相同
参数列表相同
返回值类型相同或者是其子类
访问权限不能严于父类
父类的静态方法不能被子类覆盖为非静态方法,父类的非静态方法不能被子类覆盖为静态方法(简单说:关于static关键字,要求父类与子类相同)
子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super)
父类的私有方法不能被子类覆盖
不能抛出比父类方法更多的异常
我们使用@override注解标识出重写方法,该注解只可标注在重写方法上,否则会报错。
2、OverLoad(重载) VS OverRide(重写)
比较项 | 位置 | 方法名 | 参数表 | 返回值 | 访问修饰符 |
---|---|---|---|---|---|
重写 | 子类 | 相同 | 相同 | 相同或者是其子类 | 不能严于父类 |
重载 | 同一类中 | 相同 | 不同 | 无关 | 无关 |
3、重写equals()方法
3、1关于String字符串的equals())方法
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char V1[] = value;
char V2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (V1[i] != V2 {
i){
return false;
i++;
}
return true;
}
}
return false;
}
3、2我们自己改写的equals()方法
@Override
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
//NullPointException || ClassCastException
if (anObject == null)||(anObject instanceof Dog) {
return false;
}
return
this.getName().equals(((Dog) anObject).getName);
}
3、3IDEA重写equals()方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if(o==null||getClass()!=o.getClass()) return false;
Dog dog = (Dog) o;
return strain.equals(dog.strain);
}
4、多态
“白马非马”
相当于多态,我们定义一个规则,所有的“马”都不能进城,那么我们只需要将参数写作抽象父类“马”就可以,不需要具体写你是“白马”还是“黑马还是“牛马”。
//public class Master{
// public void cure(Dog dog){
// System.out.println("狗狗被照顾了");
// }
// public void cure(Penguin penguin){
// System.out.println("企鹅被照顾了");
// }
public void cure(Pet pet){
System.out.println("宠物被照顾了");
}
}
当我们在使用某种对象的时候,我们不去直接使用该对象的对应类型,而是采取使用该对象的父类类型,此时,我们就可以称这是多态的使用
多态的前提条件:
要有继承或者实现关系
要有方法的重写
要有父类引用指向子类对象
4、1多态使用在对象声明时
这就是多态的一个表现,我们使用父类作为声明类型,而直接使用子类进行实例化
Pet p = new Dog();
4、2多态使用在方法的参数时
//public class Master{
// public void cure(Dog dog){
// System.out.println("狗狗被照顾了");
// }
// public void cure(Penguin penguin){
// System.out.println("企鹅被照顾了");
// }
public void cure(Pet pet){
System.out.println("宠物被照顾了");
}
}
我们可以使用一个方法,参数写成对应的子类,当然我们也可以写一个方法,参数写成需要调用该方法所有参数的父类,比如上面代码中提到的照顾宠物,如果我们时参数采取Pet父类进行,那么所有继承了该类的子类均可以作为这个方法的参数
4、3多态使用在方法的返回类型时
public Pet getPet(String type) {
if ("Dog".equals(type)) {
return new Dog();
} else {
return new Penguin
}
}
4、4向上/下转型
多态中存在“编译看左,运行看右”
我们就需要用到转型
Pet p = new Pet();
//等于Pet Dog = new Dog();
Pet dog = P.getPet("Dog");
//此处虽然我们的dog是以Pet进行声明,但是,真正实例化的时候是以Dog类
//一般来说,实例化都是以如下的方式进行
Dog dog = new Dog();
//即左边为声明内容,右边为实例化内容
//“编译看左,运行看右”
//在我们进行编写代码的时候我们是使用声明类去看的
//举个例子,Dog类存在特有方法:dogMethod,父类没有
//所以此时无法直接使用dog对象去执行该方法
//这个方法是报错的
//dog.dogMethod();
//除非我们将这个dog对象强制类型转化为Dog
//由于dog对象是使用Dog去实例化的
//所以Pet类型的dog对象确实可以转化为Dog类型
((Dog)dog).dogMethod();
4、5instanceof关键字
//如果你有一只企鹅,这个企鹅用Pet去声明
Pet penguin = new Penguin();
//我们吧企鹅进行转化成Dog
//((Dog)Penguin).dogMethod();
//由于penguin对象本质是一只企鹅,所以在进行转化时会转化失败
//此时会抛出ClassCassException
//类型转化异常
//关于类型有一个关键字可以进行判断
//instanceof关键字可以进行这方面操作
if(penguin instanceof Dog)
{
((Dog) penguin).dogMethod();
}else
{
((Penguin) penguin).penguinMethod();
}
5、关于abstract关键字
public abstract class Pet {
//抽象类中,允许存在抽象方法
//抽象方法没有方法体
//如果要调用抽象方法,必须要使用子类去实在该方法
public abstract void show();
}
public class Dog extends Pet{
//如果你继承的类为抽象类
//那么你就必须要实现该抽象类的所有抽象方法
//除非你也是一个抽象类
@Override
public void show(){
System.out.println("这只狗展示了信息");
}
}
public class Test(){
public static void main(String[] args){
//抽象类无法被直接实例化
//Pet p = new Pet();
Dog dog = new Dog();
dog.show();
}
}