抽象类


抽象类的来源:

  封装:对象代表什么,就得封装对应的数据,并提供数据对应的行为

  继承:将子类共有的部分提取出来,定义一个父类,子类继承父类

  弊端:子类中的方法都需要重写时,但是可能忘记或故意不重写

这时候就需要抽象方法:

  当你定义了一个抽象方法,子类必须重写这个方法,否则就会报错

  抽象方法所在的类就称为抽象类

抽象方法:

  将共性的行为抽取到父类之后,由于每个子类执行的内容是不同的,所以,在父类中不能确定具体的方法体,该方法就可以定义为抽象方法。

如何定义?

  一、抽象方法:

      public abstract 返回值类型 方法名(参数列表);

  二、抽象类:

      public abstract class 类名{}

注意事项:

  一、抽象类不能实例化(创建对象)

  二、抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类

  三、抽象类可以有构造方法

  四、抽象类的子类:

      要么重写抽象类中的所有抽象方法

      要么是抽象类

抽象类和抽象方法的意义:

  在团队开发中统一开发思路,每个子类都要强制重写这个方法

  值得注意的是:抽象类不能被实例化


接口


假如一个方法不被所有子类共有,但又被部分子类共有,为了这个功能易于维护和统一性,我们会新定义一个拥有该功能的接口,接口可以理解为一种规则,不是一种继承体系,是对行为的抽象.

如何定义一个接口

public interface 接口名{}

接口不能实例化

接口和类是实现关系,通过implements关键字表示

public class 类名 implements 接口名{}

接口的子类(实现类)

  要么重写接口中的所有抽象方法

  要么是抽象类

接口中成员的特点:

  成员变量:

    只能是常量

    默认修饰符:public static final

  构造方法:

    

  成员方法:

    只能是抽象方法

    默认修饰符:public abstract

  JDK7以前:接口中只能定义抽象方法

  JDK8的新特性:接口中可以定义有方法体的方法 (为了接口升级的时候使用)

  JDK9的新特性:接口中可以定义私有方法

新增默认方法:默认方法可以通过接口的实现对象直接调用,可以被接口的实现类重写

接口和类之间的关系:

  类和接口的关系:

     实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口

  接口和接口的关系

     继承关系,可以单继承,也可以多继承

​ *

*扩展:

  • 接口中的默认方法是抽象方法,public和abstract可以省略,而default不能省

  • 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写

  • JDK8之后新增静态方法:

  • 静态方法只能通关接口名调用,不能通关实现类名或者对象名调用,同时静态方法不能被重写 (s.eat();会出错)

    •    #### 静态方法不会被添加到虚方法表,当子类中出现同名方法时,只会调用子类中的方法
      
  • JDK9之后新增私有方法:

  • 私有方法:private void show(){}给默认方法服务

  • 静态私有方法:private static void show(){}给静态方法服务

    接口的应用:

  • 可以将多个类使用到的功能定义为接口,是各种各样行为的规则

  • 当我在调用方法时使用了接口,我就可以传递这个接口所有的实现类对象

  • public void 搬家(运输的接口 c){} (意思是:实现了这个接口的类的对象都能写进参数,

    •                                  #### 比如车和人都能使用运输接口,那车和人就都可以写进参数)
      

    适配器设计模式:

  • 设计模式(Design Pattern)是一套被反复使用,多数人知晓的、经过分类编目、代码设计经验的总结

    •      #### 使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码可靠性,程序的重用性。
      
    • (设计模式就是各种套路)

      *
      
  • 比如在某个接口中实现了十个方法,但是我们的类中只需要使用一个方法,那可以创建中间类,

  • 然后在中间类中重写所有的方法(空方法),然后用我们的类去继承这个中间类,这样就只需要重写需要的方法了

    • 一般情况下适配器对象会被设计为abstract抽象类,目的是为了防止外界创建它的对象(无意义)

  • 当一个方法中抽象方法过多,但是我们只需要其中一部分的时候,就可以使用适配器设计模式:中间类XXXXAdapter,实现对应接口


内部类


什么是内部类:

  类的五大成员:

    属性,方法,构造方法,代码块,内部类

内部类就是在类的内部再定义一个类,如:

public class Outer{
    methods1;
 public class Inner{
        methods2;
 }
}

与这两个类无关的类称为外部其他类

例:

需求:写一个javabean类描述汽车

  属性:汽车的品牌,车龄,颜色,发动机的品牌,使用年限

    如果定义一个car类,在car类中实现所有的属性,那么你要考虑到发动机实际上独立的个体

    但是发动机是随着车出现的,不会独立存在,所以需要在car中再定义发动机类

    内部类表示的事物应该是外部类的一部分

    内部类可以直接访问外部类的成员,包括私有

    外部类要访问内部类的成员,必须创建对象

内部类的种类:

  1. 成员内部类

  2. 静态内部类

  3. 局部内部类

  4. 匿名内部类----需要重点掌握

   (前面三种只需要了解)

成员内部类的注意事项:

  1.写在成员位置的,属于外部类的成员

  2.当用private修饰成员内部类之后在外界就不能直接创建内部类的对象,只能在外部类中创建

  3.当protected修饰可以在同类,同包,或者不同包的子类中访问

  4.当用public修饰,除了同类、包,或者不同包中的子类中,还可以在不同包的无关类中访问

  5.static修饰时为静态内部类而不是成员内部类

  6.在成员内部类里面,JDK16之前不能定义静态变量,JDK16之后才可以定义静态变量

成员内部类的对象:

  方法一、在外部类中编写方法,对外提供内部类的对象。(当private修饰内部类时)

  方法二、直接创建内部类的格式:外部类名.内部类名 对象民 = 外部类对象.内部类对象;

  示例:Outer.Inner oi = new Outer().new Inner();

为什么:因为我们创建的是内部类的对象,但是单独存在无意义,所以需要添加一个外部类的标识

    oi为变量名称,等号右边是对象的地址值,Inner类在Outer中,也需要new

    简单来讲就是链式编程

静态内部类:

  1.静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的则需要创建对象

  2.创建静态内部类对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();

  3.如果方法也是静态,那直接 外部类名.内部类名.方法名(); 就可以调用

局部内部类:

  1.将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量

  2.外界是无法直接使用的,需要在方法内部创建对象并使用

  3.该类可以直接访问外部类的成员,也可以访问方法内的局部变量

匿名内部类:

  1.匿名内部类本质上就是隐藏了名字的内部类

new 类名或者接口名(){
 重写方法;
};

  2.实际上大括号内才是类,实际上创建的是对象。

  3.可以用来当做对象传递给某个方法,就不需要再去创建一个对象了。

  4.匿名内部类包含了继承或实现,方法重写,创建对象。

  5.整体就是一个类的子类对象或者接口的实现类对象。