Java中的继承、方法覆盖(方法重写)、super关键字、多态

Java继承

  • 继承

继承是面向对象的一个重要的特性,它体现了类与类之间的一些逻辑关系,目的是为了代码复用(以减少开发成本)。当多个类之间有一些共同的属性(成员变量)和功能(成员方法)时,我们可以将他们共同的部分拿出来作为一个父类定义实现这些共性,这些类中可以不再定义这些共性而直接继承父类,得到这些属性和功能。
继承体现了客观事物中事物的层次关系。在Java程序中支持单继承(任何一个子类都只能有一个父类),支持多层继承,不支持多重继承。
继承关键字extends
定义类时在extends关键字后指明新定义的父类,使得在两个类之间建立继承关系。
子类、父类建议定义在多各中Java文件中。

	public class <父类类型>() {
		<定义成员变量>;
		public <成员方法的返回值> <成员方法名称>() {
			<成员方法中要实现的逻辑功能语句>;
		}
	}
	public class <子类类型> extends <父类类型> {
		
	}

这样就简单的完成了一个逻辑功能。
子类只能继承父类的以public、protected、无修饰的访问修饰符修饰的成员变量和成员方法,也就是说父类中被private修饰的成员变量和成员方法不能被子类继承。构造方法不能被继承。
Object类是所有类的父类。

  • instanceof(运算符)关键字
    <对象名> instanceof <本类类型>运算结果为true
    <对象名> instanceof <父类类型>运算结果为true
    <父类引用指向子类对象的对象名> instanceof <父类类型>运算结果为true
    <父类引用指向子类对象的对象名> instanceof <子类类型>运算结果为true
    <接口实现类的对象名> instanceof <接口类型类型>运算结果为true
    <对象> instanceof <类>运算符的作用是判断对象是否是这个类或它的子类产生的,是否实现了某个接口。
	public class Demo {
    public static void main(String[] args) {
    	<父类> <对象名1> = new <父类构造方法>();
    	<子类> <对象名2> = new <子类构造方法>();
    	<父类> <对象名3> = new <子类构造方法>();
    	System.out.println(<对象名1> instanceof <父类类型>);//true
    	System.out.println(<对象名2> instanceof <子类类型>);//true
    	System.out.println(<对象名2> instanceof <父类类型>);//true
    	System.out.println(<对象名3> instanceof <父类类型>);//true
    	System.out.println(<对象名3> instanceof <子类类型>);//true
    	System.out.println(<接口实现类的对象名> instanceof <接口类型>);//true
    }
}
  • 继承的优、缺点
    继承为了实现代码复用,提高代码维护性,让类与类之间产生联系(多态的前提)。但与此同时提高了类与类之间的耦合度。
    程序设计目的:高内聚、低耦合。
  • 方法覆盖(方法重写)override

方法覆盖只可以重写父类中允许子类访问的方法(非private的方法)
Java程序在继承体系中,子类可以根据各自的需求重新定义继承父类的成员方法,即子类可以改写父类方法所实现的功能。
子类重写的方法必须与父类中被重写的方法有相同的方法名称、参数类型参数个数且一一对应。
子类中重写的方法访问权限修饰符不能比被重写的方法访问权限修饰符小。
子类中重写的方法不能抛出新的异常。
在子类要覆盖的方法上一行添加@Override语句来来提高代码的阅读性。当@Override下的方法不是覆盖父类方法时,编译器会报错。
方法重写使得Java程序支持多态,而多态性是面向对象的程序设计的特性之一。当相同方法被不同子类对象调用时,产生不同的操作,以实现不同的逻辑功能。

  • super关键字

静态方法中不能使用this和super。因为this和super代表着本类对象和父类对象。静态方法中不能应用非静态成员和非静态方法。
引入super的一部分原因是子类和父类的成员变量和成员方法(重写后的方法和重写前的方法)重名时,所区分的一种方式。一般地在某个{}内使用成员变量时,现在本{}语句体中查找同名变量,假如没有就在本类地成员变量中查找,还没有就在父类地成员变量中查找,还没找到的话就报错。
当子类在重写父类方法后,使用父类被覆盖的方法时,用super.<父类方法名>;来调用父类的成员方法。也可以通过super();调用父类中的构造方法,调用位置只能是在子类的构造方法中的第一条,且父类中有相关构造方法。另外每个子类的构造方法中第一个语句默认都是super();。当父类中定义了构造方法后(没有定义默认的无参构造方法),子类不能使用父类的默认构造方法。

多态

Java中允许父类引用指向子类对象。对象不仅可以作为本身的类型引用,也可以作为其父类(基类)的引用。

<父类类型> <对象名> = new <子类构造方法>();

用此对象名来引用同名的成员变量时,编译看左边(编译器检错机制需要在父类中存在该成员变量 ),运行看左边(执行时用父类中的成员变量的值来运算)
用此对象名来引用 同名的成员方法时,编译看左边,运行看右边(执行时用子类重写后的方法来执行)
以上形式等同于

<父类类型> <父类对象名> = new <父类构造方法>();
<父类类型> <对象名> = <父类构造方法>();
public class Father {
    int num = 0;

    public Father() {
        System.out.println("Father constructor");
    }

    public void method() {
        System.out.println("Father method()");
    }
}

public class Me extends Father {
    int num = 1;
    public Me() {
        System.out.println("Me constructor");
    }

    @Override
    public void method() {
        System.out.println("Me method()");
    }

    public void meMethod() {
        System.out.println("meMethod()");
    }
}
public class PolymorphismDemo {// Polymorphism多态
    public static void main(String[] args) {
        Father father = new Me();
        System.out.println(father.getClass());
        System.out.println(father.num);
        System.out.println(((Me) father).num);
        father.method();
        ((Me) father).method();
        ((Me) father).meMethod();
    }
}
//结果
Father constructor
Me constructor
class org.westos.Polymorphism.Me
0
1
Me method()
Me method()
meMethod()
public class Test {
    public static void main(String[] args) {
        Me me = new Me();
        System.out.println(me.getClass());
        Father father = (Father) me;
        System.out.println(father.getClass());
        System.out.println(((Me) father).getClass());
        System.out.println(father.num);
        System.out.println(((Me) father).num);

    }
}
//结果
Father constructor
Me constructor
class org.westos.Polymorphism.Me
class org.westos.Polymorphism.Me
class org.westos.Polymorphism.Me
0
1

你可能感兴趣的:(Java中的继承、方法覆盖(方法重写)、super关键字、多态)