java面向对象之继承

 在java中,面向对象毫无疑问是java的重中之重,今天我们来看一看java面向对象的三大特性之一继承。

  首先我们来了解一下类的结构是怎样的?

  类中主要有成员属性,成员方法,静态属性,静态方法,构造方法(暂不考虑代码块)。成员属性和成员方法是属于对象的,静态属性和静态方法是属于类的,如下图所示。

 类的结构我们知道了(为后面做铺垫的),那么接下来就正式的进入了我们的主题,继承!

  1.什么是继承?

(1)用来提高代码的复用性

(2)将相同的功能模块封装到方法中需要使用时调用方法达到代码复用的目的

(3)通过继承将多个类中的相同的类容摘取出来,变成一个新类,让其他类和当前的新类产生关系,达到代码复用性的目的

  2.怎么样才能继承?

  使用关键字extends,如下所示,B继承A, A是B的父类,B是A的子类。当一个类不显示的继承其它类时,默认继承Object类,Object是所有的父类。在java中只有直接父类和间接父类关系,没有兄弟关系,爷孙关系。

 

使用继承以后就可以子类就是可以使用父类中的方法了,如下图所示,子类的对象可以直接调用父类中方法,而不用重新定义方法。然而其实很多时候因为子类的需求和父类的需求是不同的,所以需要重写父类的方法。这样的话,代码的复用率就低了。另外,java中是单继承的,不允许出现多继承,当一个类已经继承了这个类就不会继承其它类,代码的可扩展性就大大的降低了,其次,一旦类的继承链越来越长的,维护的成本就变的相当高了,当改动其中一个类时,很多类都需要进行改动,可能还不如重构来的快。大多时候我们都是面向接口编程的,这个话题我们有空可以再来聊一聊!

 

 3,父类的东西,子类可以全部继承吗?

  不,当然不是;

  3.1权限修饰符的继承问题

  被private修饰的,是不可以被继承的,因为private修饰的只能在本类中可见,子类是不可见的;另外父类被protected或public修饰的,子类是可以继承的;被默认修饰符修饰的只能在同包下的子类是可以继承的;

  3.2 构造器的继承问题

  构造器是不会被子类继承的,但子类的对象在初始化时会默认调用父类的无参构造器,当父类显示写了有参构造器,且没有无参构造器。子类继承父类的时候必须显示的调用父类的有参构造器。调用的方式可以使用super(a,b)来调用;

  3.3 static修饰符的继承问题

  子类是不会继承父类被static修饰的方法和变量,但是可以调用;如图所示,this.a()就会报错,普通方法的继承this.method_a()就不会报错;

 

   4,方法的重写(覆盖)

  重写是发生在方法层面上的,属性是不会重写的,可以被隐藏,隐藏是针对于静态方法和静态属性的。另外重写是针对于实例方法的,子类的实例方法不能覆盖父类的静态方法,子类的静态方法不能隐藏父类的实例方法;当子类需要扩充父类的功能时,需要会对父类的方法进行重写,那么重写必须满足哪些条件呢?,如下图所示,

  

   4.1,即要重写的方法的方法名和参数列表必须相同,可以在要重写的方法的上方添加@Override注解,来判断是否正确的进行了重写;

  4.2 即子类的返回值类型和抛出的异常类型必须要小于等于父类的类型

 

  4.3 要重写的方法的权限修饰符必须要大于等于父类方法的权限,不然就会报错,

 

注意:重写是对于实例方法而言的,隐藏是对于静态方法和属性而言的(主要是由父类和子类中相同的方法名和属性名引起的),重写是受RTTI(运行时检查)约束的,即运行期间才知道该方法属于哪个类的,隐藏是不受该约束的,即编译期间就可以知道该方法和属性属性属于哪个类的。

下面有一道网上的面试题,主要针对于重写和隐藏的,小伙伴可以做做看!!!

package com.shsxt.test;


public class Test07 {
public static void main(String[] args) {

Circle circle=new Circle();
System.out.println(circle.name);
circle.printType();
circle.printName();

Shape shape = new Circle();
System.out.println(shape.name);
shape.printType();
shape.printName();
}
}

class Shape {
public String name = "shape";


public void printType() {
System.out.println("this is shape");
}

public static void printName() {
System.out.println("shape");
}
}

class Circle extends Shape {
public String name = "circle";


public void printType() {
System.out.println("this is circle");
}

public static void printName() {
System.out.println("circle");
}
}

答案:

posted @ 2019-09-18 16:35  那些年的代码  阅读(294)  评论(0编辑  收藏  举报