继承

  • 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
  • 多个类可以称为子类,单独这个类称为父类、超类或者基类。
  • 子类可以直接访问父类中的非私有的属性和行为。
  • 通过 extends 关键字让类与类之间产生继承关系。

具体实现为,通过extends关键字让类与类之间产生继承关系:

class SubDemo extends Demo{}    //SubDemo是子类,Demo是父类

继承提高了代码的复用性,让类与类之间产生关系,是多态的前提。

super和this的区别

super是一个关键字,代表父类的存储空间标识。(可以理解为父亲的引用)

  • this代表对象的引用(谁调用就代表谁);
  • super代表当前子类对父类的引用。

使用场景

  • 当子父类出现同名成员时,可以用super进行区分
  • 子类要调用父类构造函数时,可以使用super语句

具体用法

  1. 成员变量

    mark

  2. 构造方法

    mark

  3. 成员方法

    mark

注意:

  • super();和this();都是在构造函数的第一行,不能同时出现(this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过)
  • this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块

举个栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Person { 
public static void prt(String s) {
System.out.println(s);
}

Person() {
prt("父类·无参数构造方法: "+"A Person.");
}//构造方法(1)

Person(String name) {
prt("父类·含一个参数的构造方法: "+"A person's name is " + name);
}//构造方法(2)
}

public class Chinese extends Person {
Chinese() {
super(); // 调用父类构造方法(1)
prt("子类·调用父类”无参数构造方法“: "+"A chinese coder.");
}

Chinese(String name) {
super(name);// 调用父类具有相同形参的构造方法(2)
prt("子类·调用父类”含一个参数的构造方法“: "+"his name is " + name);
}

Chinese(String name, int age) {
this(name);// 调用具有相同形参的构造方法(3)
prt("子类:调用子类具有相同形参的构造方法:his age is " + age);
}

public static void main(String[] args) {
System.out.println("第一条语句执行结果为:");
Chinese cn = new Chinese();
System.out.println("第二条语句执行结果为:");
cn = new Chinese("codersai");
System.out.println("第三条语句执行结果为:");
cn = new Chinese("codersai", 18);
}
}

运行结果为:

mark

抽象类

  • Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类
  • 抽象方法和抽象类都必须被abstract关键字修饰
  • 抽象类不可以用new创建对象,因为调用抽象方法没意义
  • 抽象类中的抽象方法要被使用,必须由子类复写其所有的抽象方法后,建立子类对象调用; 如果子类只覆盖了部分的抽象方法,那么该子类还是一个抽象类
  • 抽象类中可以有抽象方法,也可以有非抽象方法,抽象方法用于子类实例化
  • 如果一个类是抽象类,那么,继承它的子类,要么是抽象类,要么重写所有抽象方法。
    特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象

栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
abstract class 葵花宝典 {
public abstract void 自宫();
}

class 岳不群 extends 葵花宝典 {
public void 自宫(){
System.out.println("剪刀");
}
}

class 林平之 extends 葵花宝典{
public void 自宫(){
System.out.println("指甲刀");
}
}
class AbstractTest {
public static void main(String[] args) {
岳不群 岳 = new 岳不群();
岳.自宫();

林平之 林 = new 林平之();
林.自宫();
}
}

抽象类不能被实例化,为什么还有构造函数?

只要是class定义的类里面就肯定有构造函数。抽象类中的函数是给子类实例化的。

一个类没有抽象方法,为什么定义为抽象类?

不想被继承,还不想被实例化。

抽象关键字abstract不可以和哪些关键字共存?

final:如果方法被抽象,就需要被覆盖,而final是不可以被覆盖,所以冲突。

private:如果函数被私有了,子类无法直接访问,怎么覆盖呢?

static:不需要对象,类名就可以调用抽象方法。而调用抽象方法没有意义。

接口

接口是抽象方法和常量值的集合。从本质上讲,接口是一种特殊的抽象类,这种抽象类只包含常量和方法的定义,而没有变量和方法的实现

格式:interface 接口名{}(注意没有“class”)

实现:class 类名 implements 接口名 {}

接口的成员特点:

成员常量:public static final,接口里定义的变量是全局常量,而且修饰符只能是这三个关键字,都可以省略,常量名要大写

成员方法:public abstract,接口里定义的方法都是抽象的,两个修饰符关键字可省略

推荐:永远手动给出修饰符

抽象类与接口的区别

  • 成员变量:
    • 抽象类能有变量也可以有常量
    • 接口只能有常量
  • 成员方法:
    • 抽象类可以有非抽象的方法,也可以有抽象的方法
    • 接口只能有抽象的方法
  • 构造方法:
    • 抽象类有构造方法
    • 接口没有构造方法
  • 类与抽象类和接口的关系:
    • 类与抽象类的关系是继承 extends
    • 类与接口的关系是实现 implements

一个类可以实现多个接口吗?

答案是肯定可以的,接口本身就是解决多重继承衍生的产物,如果不能实现多个接口那接口姐没有什么意义了。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//A接口
interface A{
public int getA();
}
//B接口
interface B{
public int getB();
}
//实现了某个接口必须实现其全部的方法
public class ImpAB implements A,B{
public int getA() {
return 0;
}
public int getB() {
return 0;
}
}

内部类

将一个类定义在另一个类里面,里面的那个类就称为内部类

  • 内部类可以直接访问外部类的成员,包括私有成员
  • 外部类要访问内部类的成员,必须要建立内部类的对象
  • 内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号
  • 内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的

成员内部类

mark

静态内部类

mark

局部内部类

mark

匿名内部类

mark

本文主要内容转载于:Java 继承详解