JAVA(抽象类与接口的区别&重载与重写&内存泄漏)

1.抽象类与接口 1)抽象类
抽象类是对一种事物的抽象,即对类的抽象,表示同类事物的共性。通过继承使用抽象类,体现了强耦合关系。

  • 一个类若声明为抽象类,必须被abstract键字修饰;
  • 抽象类不能被实例化,可以有构造器、初始代码块、内部类,main方法;
  • 一个类若包含了抽象方法,则一定是抽象类;但抽象类不一定含有抽象方法;
  • 抽象方法只能声明不能有函数体,且必须是public(默认)或protected,否则不能被子类继承;
  • 抽象类中可以有成员方法和成员变量,没有权限要求;
  • 子类继承抽象类时,必须实现所有抽象方法,否则子类也必须声明为抽象类;
  • abstract不能修饰成员、局部变量;
2)接口
接口设计的目的是对类的行为进行约束,强制要求不同的类具有相同的行为。
  • 接口中变量类型只能是 public static final(默认);
  • 接口中的方法只有方法声明无方法体,且必须被public abstract修饰;
  • JAVA8支持接口中包含具体方法,可以是静态方法(static)和默认方法(default);
public interface infa{ int a = 1; void f(); //抽象方法 default void f1(){//非静态加关键字default ... } static void f2(){//静态方法 ... } }

  • 接口中不能有构造器和初始化块;
2.重载与重写 1)重写(Override)
重写是子类对父类允许访问的方法的实现过程进行重新编写,是父类与子类之间多态性的一种表现(类间多态),返回值和形参都不能改变。重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。
方法重写规则:
  • 参数列表必须完全与被重写方法相同;
  • 返回类型必须完全与被重写方法的返回类型相同;(public > protected > default > private)
  • 访问权限不能比父类中被重写的方法的访问权限更低;
  • 重写方法能够抛出任何非强制性异常,无论被重写的方法是否抛出异常。但是,重写方法不能抛出新的强制性异常,或者比被重写方法声明的更宽泛的强制性异常;
  • 声明为final的方法不能被重写;
  • 声明static的方法不能被重写,但是可能够被再次声明;(静态方法属于类)
  • 子类和父类在同一个包中,那么子类能重写父类的所有方法,除了声明为final和private的方法;
  • 子类和父类不在同一包中,那么子类只能重写父类的声明为public和protected的非final方法;
  • 构造方法不能被重写;
2)重载(Overload)
重载是在一个类里面,体现了一个类的多态性,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法/构造器都必须有一个独一无二的参数类型表;
方法重载规则:
  • 被重载的方法必须改变参数列表;
  • 被重载的方法可以改变返回类型;
  • 被重载的方法可以改变访问修饰符;
  • 被重载的方法可以声明新的或更广的受检异常;
  • 方法能在同一类中或在一个子类中被重载;
  • 无法以返回值类型作为重载函数的标准;
3.内存泄漏 1)内存泄漏的原因
内存泄漏是指无用对象持续占有内存或无用对象得不到及时的释放,从而导致内存空间的浪费称为内存泄漏。长生命周期的对象持有短生命周期的对象的引用就很可能发生内存泄漏,即根搜索进行可达性分析时目标可达,但实际目标已经无用。
2)造成内存泄漏的几种情况
  • 静态集合类引起内存泄漏:像HashMap、ArrayList等,若声明为静态变量,其生命周期与应用程序一致,它们所引用的所有对象也不能被释放;
  • 当集合内的对象属性被修改后,再调用remove()方法将不起作用;
  • 监听器:在被监听对象释放后没有删除对应的监听器,导致内存泄漏;
  • 连接:数据库连接、网络连接、IO连接,除非显示的调用其close()方法将其关闭,否则不会自动被GC回收;
  • 单例模式:单例对象在初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部的引用,那么这个被引用对象将不能被JVM正常回收,导致内存泄漏;
  • 内部类和外部模块的引用;
【JAVA(抽象类与接口的区别&重载与重写&内存泄漏)】3)如何检查内存泄漏?
  • dump出堆中的信息 jmap -dump
  • 使用分析工具,找出内存占用超出预期的嫌疑对象;
  • 必要时,分析嫌疑对象与其它对象的引用关系;
  • 查看源代码,找出嫌疑对象数量过多的原因;

    推荐阅读