重载、重写点睛之笔
一、对象类型中的基本知识
java中通常使用继承来提高代码的复用性,子类自动继承父类的方法和属性,使得子类中不在存在重复的代码,其中,被继承的类称为父类,继承的类称为子类,子类中的方法被称为重写方法,父类中的方法被称为被重写方法,用extends关键字来表示一个类继承来另一个类,值得注意的是,在继承过程中,子类可以定义特定的属性和方法,也正是因为有了继承,才有了多态。
1.向上转型
父类引用指向子类对象称为向上转型;向上转型的时候会丢失掉自己的特有行为
假设有一个Gril类,里面包含了一个smile()方法,MMGril继承了Gril类,重写了smile方法,并有自己特有的一个cry()方法,在测试TestMMGril类中,创建一个MMGril对象g,Gril g = new MMGril();这句代码就采用了向上转型的方法,父类(Gril类)引用指向子类(MMGril类)对象(g)
package test;
class Gril{
public void smile(){
System.out.println("Gril smile ...");
}
}
class MMGril extends Gril{
public void smile(){
System.out.println("MMgril smile sweat ...");
}
public void cry(){
System.out.println("MMGril cry ...");
}
}
public class TestMMGril {
public static void main(String[] args) {
//创建一个MMGril对象
//父类引用指向子类对象
Gril g = new MMGril();
g.cry();
}
}
但是我们可以看到,执行结果提示cry()方法在Gril类中未定义,从而可以看出,向上转型时,子类会丢失掉自己的特有行为。
2.向下转型
向下转型:将指向子类对象的父类引用强制赋给子类引用
前提条件:指向子类对象的父类引用
同样的范例,可以在执行窗口看到,当我们创建一个Gril对象后无法强制转换为子类对象,mm=(MMGril)gril;转换失败,因为向下转型强制转换的前提条件一定是指向子类对象的父类引用,而且MMGril mmGril = new Gril();是一种错误的表示,因为子类的引用指向父类对象是不允许的
public class TestMMGril {
public static void main(String[] args) {
Gril g = new MMGril();
g.smile();
//向下转型:
MMGril mm = (MMGril)g;
mm.cry();
//创建一个Gril对象
Gril gril = new Gril();
mm=(MMGril)gril;
MMGril mmGril = new Gril();//(错误的表示)
}
}
在分不清父类是否引用子类对象的情况下,可以通过以下判断来确定是否引用正确
public class TestMMGril {
public static void main(String[] args) {
Gril g = new MMGril();
g.smile();
MMGril mm = (MMGril)g;
mm.cry();
Gril gril = new Gril();
//判断gril是不是指向子类对象
if(gril instanceof MMGril){
mm=(MMGril)gril;
}else{
System.out.println("gril没有指向子类对象");
}
}
}
二、重载与重写
1.重载与重写的区别
(1)范围不一样,重载针对于类。重写针对继承关系(父类-子类、抽象类-实现类、接口-实现类)
(2)重载的方法可以添加任意的权限修饰符,重写的方法权限修饰符一般跟父类的重写方法权限修饰符是一样的;子类重写方法的权限修饰符不能低于父类的重写方法的权限修饰符; 在定义父类或者抽象类或者接口时候,需要子类重写的方法不能私有;
(3)重载:编译期,早确定;重写:执行期,晚确定
(4)其中重写的权限要大于等于被重写的权限
(5)重写方法必须和被重写方法有相同的方法名称、参数列表、返回值类型;(注:返回值可以为父类中返回值的子类型.参数若为子类,则不是重写是重载)
(6)重写方法不能使用比被重写方法更严格的访问权限;
(7)重写方法不能声明抛出比被重写方法范围更大的异常类型。
范例(在控制台输出字符串)
重载:方法名相同,参数列表不同,类的权限可以是任意的
范例中method1()是父类中需要重写的方法,带参数print()方法是重载,利用参数类型不同
package overloadoverridecompare;
class Parent{
/**
* 被重写方法,子类重写方法的权限修饰符不能低于父类
* 父类或者抽象类或者接口时候,需要子类重写的方法不能私有;
*/
protected void method1(){
}
}
class Child1 extends Parent{
@Override
public void method1() {
System.out.println("输出Child1信息...");
}
}
class Child2 extends Parent{
/**
* 重写方法;重写了method1方法
*/
@Override
public void method1() {
System.out.println("输出Child2信息...");
}
/**
* print方法被重载
* @param n
*/
public void print(int n){
System.out.println(23);
}
protected void print(String str){
System.out.println("大幅度");
}
private void print(boolean bol){
System.out.println(true);
}
}
public class TestParent {
public static void showMethod(Parent p){
p.method1();
}
public static void main(String[] args) {
showMethod(new Child1());
showMethod(new Child2());
Child2 c = new Child2();
//c.print(43);
//c.print("wr");
}
}