Java面向对象笔记(二)

继承

继承可以看成是类与类之间的衍生关系。比如狗类是动物类,牧羊犬类又是狗类。于是我们可以说狗类继承了动物类,而牧羊犬类就继承了狗类。于是狗类就是动物类的子类(或派生类),动物类就是狗类的父类(或基类)。

所以继承需要符合的关系是:is-a,父类更通用,子类更具体。

语法:

class 子类 extends 父类

为什么需要继承?

如果有两个类相似,那么它们会有许多重复的代码,导致后果就是代码量大且臃肿,后期的维护性不高。通过继承就可以解决这个问题,将两段代码中相同的部分提取出来组成一个父类,实现代码的复用。

继承的特点:

  • 子类拥有父类除 private 以外的所有属性和方法。
  • 子类可以拥有自己的属性和方法。
  • 子类可以重写实现父类的方法。
  • Java 中的继承是单继承,一个类只有一个父类。

注:Java 实现多继承的一个办法是 implements(实现)接口,但接口不能有非静态的属性,这一点请注意。

super

super 关键字在子类内部使用,代表父类对象。

  1. 访问父类的属性 super.属性名
  2. 访问父类的方法 super.bark()
  3. 子类构造方法需要调用父类的构造方法时,在子类的构造方法体里最前面的位置:super()

多态

多态是指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。多态也称作动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。

通俗地讲,只通过父类就能够引用不同的子类,这就是多态,我们只有在运行的时候才会知道引用变量所指向的具体实例对象。

多态的实现条件

Java 实现多态有三个必要条件:继承、重写和向上转型(即父类引用指向子类对象)。

只有满足上述三个条件,才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。

多态的实现方式

Java 中多态的实现方式:继承父类进行方法重写,抽象类和抽象方法,接口实现。

抽象类

在定义类时,前面加上 abstract 关键字修饰的类叫抽象类。

抽象类中有抽象方法,这种方法是不完整的,仅有声明而没有方法体。抽象方法声明语法如下:

abstract void f();  //f()方法是抽象方法

那我们什么时候会用到抽象类呢?

  1. 在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法。也就是说抽象类是约束子类必须要实现哪些方法,而并不关注方法如何去实现。
  2. 从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随意性。

所以由上可知,抽象类是限制规定子类必须实现某些方法,但不关注实现细节。

那抽象类如何用代码实现呢,它的规则如下:

  1. 用 abstract 修饰符定义抽象类。
  2. 用 abstract 修饰符定义抽象方法,只用声明,不需要实现。
  3. 包含抽象方法的类就是抽象类。
  4. 抽象类中可以包含普通的方法,也可以没有抽象方法。
  5. 抽象类的对象不能直接创建,通常是定义引用变量指向子类对象。

接口

接口用于描述类所具有的功能,而不提供功能的实现,功能的实现需要写在实现接口的类中,并且该类必须实现接口中所有的未实现方法。

接口的声明语法格式如下:

修饰符 interface 接口名称 [extends 其他的接口名] {
        // 声明变量
        // 抽象方法
}

注意点

在 Java8 中:

  • 接口不能用于实例化对象。
  • 接口中方法只能是抽象方法、default 方法、静态方法。
  • 接口成员是 static final 类型。
  • 接口支持多继承。

在 Java9 中,接口可以拥有私有方法和私有静态方法,但是只能被该接口中的 default 方法和静态方法使用。

多继承实现方式:

修饰符 interface A extends 接口1,接口2{

}

修饰符 class A implements 接口1,接口2{

}

内部类

将一个类的定义放在另一个类的定义内部,这就是内部类。而包含内部类的类被称为外部类。

内部类的主要作用如下:

  1. 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类
  2. 内部类的方法可以直接访问外部类的所有数据,包括私有的数据
  3. 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
  4. 内部类允许继承多个非接口类型(具体将在以后的内容进行讲解)

成员内部类

成员内部类的使用方法:

  1. Student 类相当于 People 类的一个成员变量,所以 Student 类可以使用任意访问修饰符。
  2. Student 类在 People 类里,所以访问范围在类里的所有方法均可以访问 People 的属性(即内部类里可以直接访问外部类的方法和属性,反之不行)。
  3. 定义成员内部类后,必须使用外部类对象来创建内部类对象,即 内部类 对象名 = 外部类对象.new 内部类();
  4. 如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字。

注:成员内部类不能含有 static 的变量和方法,因为成员内部类需要先创建了外部类,才能创建它自己的。

静态内部类

静态内部类通常被称为嵌套类

静态内部类是 static 修饰的内部类,这种内部类的特点是:

  1. 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问。
  2. 如果外部类的静态成员与内部类的成员名称相同,可通过 类名.静态成员 访问外部类的静态成员;如果外部类的静态成员与内部类的成员名称不相同,则可通过 成员名 直接调用外部类的静态成员。
  3. 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名 = new 内部类();

局部内部类

局部内部类,是指内部类定义在方法和作用域内。

匿名内部类

匿名内部类,顾名思义,就是没有名字的内部类。正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写。但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口。

匿名内部类是不能加访问修饰符的。要注意的是,new 匿名类,这个类是要先定义的, 如果不先定义,编译时会报错该类找不到。

因为匿名内部类没名字,是用默认的构造方法的,无参数的,如果需要该类有带参数的构造方法

posted @ 2020-11-20 15:41  lovivi  阅读(103)  评论(0)    收藏  举报