继承&多态&重写&重载 理解小结

xiaoxiao2021-02-28  41

java面向对象里边包含了:继承 多态 重载 重写 下面是查询到的有用资料和自己的理解的结合 一、继承 1、继承:继承顾名思义,就是子类继承了父类的特征(java里边的特征是方法)。可以使用 extends 和 implements 这两个关键字来实现继承。 区别:extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承,JAVA中不支持多重继承,但是可以用接口来实现,extends只能继承一个类,implements可以实现多个接口.注:extend可以继承一个接口,但仍是一个接口,也需要implements之后才可用 e.g. class A extends B implements C,D,E 2、作用:先明确,大量重复的代码在编程中是十分不好的。如果我们想编写两个类,牛和马,那么他们共同的方法都有吃草 (1)extends 关键字例子

public class horse{ private String name; public horse(String name){ this.name = name; } public void eatGrass(){} public void sleep(){} } public class cow{ private String name; public cow(String name){ this.name = name; } public void eatGrass(){} public void sleep(){} }

除了类型不一样,其他都一样,显得累赘。如果用了继承,让代码更简洁,变成总-分关系.两个方法直接继承了,修改以后:

public class grassAnimal{ private String name; public grassAnimal(String name){ this.name = name; } public void eatGrass(){} public void sleep(){} } public horse extends grassAnimal{ public horse(String name){ super(name); } } public cow extends grassAnimal{ public horse(String name){ super(name); } }

注1:如何调用horse的sleep方法

grassAnimal a = new horse("horse");//向上转型 a.sleep();

但是如果horse有一个方法run,下面这样的写法是错的,因为编译的时候是使用grassAnimal的run方法来检查,如何能通过编译,运行的时候,才采用horse的run方法

grassAnimal a = new horse("horse"); a.run();

应该改成:

horse a = new horse("horse"); a.sleep();

下面这个例子更加清楚:

注2:一个例子

public class Wine { public void fun1(){ System.out.println("Wine 的Fun....."); fun2(); } public void fun2(){ System.out.println("Wine 的Fun2..."); } } public class JNC extends Wine{ /** * @desc 子类重载父类方法 * 父类中不存在该方法,向上转型后,父类是不能引用该方法的 * @param a * @return void */ public void fun1(String a){ System.out.println("JNC 的 Fun1..."); fun2(); } /** * 子类重写父类方法 * 指向子类的父类引用调用fun2时,必定是调用该方法 */ public void fun2(){ System.out.println("JNC 的Fun2..."); } } public class Test { public static void main(String[] args) { Wine a = new JNC(); a.fun1(); } }

结果

Wine 的Fun..... JNC 的Fun2...

只是因为实例化的JNC并没有fun1()无参数的方法,所以只能调用Wine的

(2)implement 如果使用interface来定义grassAnimal

public interface grassAnimal { public void eatGrass(); public void sleep(); } public class cow implements grassAnimal { } public class horse implements grassAnimal { }

3、构造器 (1)解释:两种情况:父类的构造器没有参数,系统自动调用父类的无参构造器;父类的构造器有参数,需要通过super关键字才能调用父类的构造器(具体看例子分析) (2)举例:

class SuperClass { private int n; SuperClass(){ System.out.println("SuperClass()"); } SuperClass(int n) { System.out.println("SuperClass(int n)"); this.n = n; } } class SubClass extends SuperClass{ private int n; SubClass(){ super(300); System.out.println("SubClass"); } public SubClass(int n){ System.out.println("SubClass(int n):"+n); this.n = n; } } public class TestSuperSub{ public static void main (String args[]){ SubClass sc = new SubClass(); SubClass sc2 = new SubClass(200); } }

输出结果

SuperClass(int n) SubClass SuperClass() SubClass(int n):200

为什么会有第三句的出现呢? 解释: 1、子类不能继承父类的构造器。 2、继承父类的时候,构造器不写super,这个时候,编译器会自动地添加一个空参数的缺省super构造器(父类无参数的构造器),此时如果父类中没有空参数的缺省构造器,那就会导致一个编译错误。(意思是,子类的每一个方法都有super,如果有参数,那就用父类有参数的构造器,如果不写的话,编译器依旧会给你加上super,采用父类无参数的构造器,如果不存在这个无参数构造器,编译出错) 例如:subClass的第二个方法

public SubClass(int n){ System.out.println("SubClass(int n):"+n); this.n = n; }

补全后是,如果SuperClass没有空的构造器就编译出错了

public SubClass(int n){ super(); System.out.println("SubClass(int n):"+n); this.n = n; }

二、重载和重写 菜鸟教程 (图借鉴了菜鸟教程)

重载:Overloading (好多种,只是参数不同) 重写:Overriding(改变这个方法的实现方式)

三、多态 1、重写 2、接口 3、抽象方法

抽象类不能被实例化,只能被其他类继承继承抽象类的子类必须把抽象类中的所有抽象成员都重写(实现)(除非子类也是抽象类)抽象类就是为了重写→多态(代码重用)

三种实现

引用看到的博客的一段话:“如何区分多态和继承” 继承:子类继承父类中所以的属性和方法,但是对于private的属相和方法,由于这个是父类的隐私,所以子类虽然是继承了,但是没有可以访问这些属性和方法的引用,所以相当于没有继承到。很多时候,可以理解为,没有继承。 多态:就是父类引用可以持有子类对象。这时候只能调用父类中的方法,而子类中特有方法是无法访问的,因为这个时候(编译时)你把他看作父类对象的原因,但是到了运行的时候,编译器就会发现这个父类引用中原来是一个子类的对像,所以如果父类和子类中有相同的方法时,调用的会是子类中的方法,而不是父类的。 可以这么说:编译时看父类,运行时看子类。

转载请注明原文地址: https://www.6miu.com/read-2624315.html

最新回复(0)