欢迎光临
我们一直在努力

JAVA零基础笔记9,10,11:三个修饰符,接口,内部类

⭐三个修饰符

♦一、abstract(抽象的)

1. abstract可以用于修饰类

   (1) 被abstract修饰的类称为抽象类

   语法:abstract class 类名{}

   (2) 抽象类编译之后生成独立的.class文件

   (3) 抽象类不能单独创建对象,但是可以声明引用

   (4) 抽象类中可以定义成员变量和成员方法

   (5) 抽象类中有构造方法,抽象类中构造方法供子类创建对象,先去完成父类对象的创建时应用。

2. abstract可以用于修饰方法

   (1) 被abstract修饰的方法称为抽象方法

   (2) 抽象方法只有方法的声明部分,没有方法的实现部分(连{}都没有)

   语法:访问修饰符 abstract 返回值类型 方法名(形参列表);

   注意:访问修饰符和 abstract 之间没有位置的先后顺序。

   (3) 抽象方法只能定义在抽象类中;但是抽象类中既可以有抽象方法,也可以有非抽象方法。

   (4) 注意:如果子类继承抽象类,子类不想成为抽象类,则需要覆盖父类(抽象类)中所有的抽象方法,否则子类也必须定义为抽象类。

3. 抽象类的作用:强制使用多态。

♦二、static(静态的)

1. static可以用于修饰属性【开发应用重点】

   (1) 被static修饰的属性称为静态属性、静态变量、类变量

   (2) 语法:访问修饰符 static 数据类型 属性名;

   访问修饰符 static 数据类型 属性名 = 值;

   注意:访问修饰符和 static 没有先后位置的要求。

   (3) 特点:静态属性是全类共有的属性,与创建多少对象没有关系。

   (4) 应用:

   a. 对象名.静态属性名 // 不建议使用

   b. 类名.静态属性名 // 建议使用

public class TestStatic{

public static void main(String[] args){

MyClass mc1 = new MyClass();

MyClass mc2 = new MyClass();

mc1.value = 50;

mc1.b = 48;

System.out.println("mc1.value="+mc1.value); // 50

System.out.println("mc1.b="+mc1.b);

System.out.println("mc2.value="+mc2.value); // 10

System.out.println("mc2.b="+mc2.b);

}

}

class MyClass{

int value = 10; // 实例变量

static int b = 30; // 静态变量、类变量、静态属性

}

2. static 可以用于修饰方法【开发应用重点】

   (1) 被 static 修饰的方法称为静态方法。

   (2) 语法:访问修饰符 static 返回值类型 方法名(形参列表) { // 方法的实现 }

   注意:访问修饰符和 static 没有位置先后要求。

   (3) 使用:类名.静态方法名(实参);

   对象名.静态方法名(实参); // 不建议使用

   (4) 注意:

   a. 静态方法中只能直接访问本类的静态成员(静态属性和静态方法)

   b. 静态方法中不能直接访问本类的非静态的成员(非静态的属性和方法)

   c. 非静态方法中既可以访问本类的非静态成员(实例变量和成员方法),也可以直接访问本类的静态成员(静态属性和方法)

   d. 静态方法中不能使用 this/super 关键字

   e. 静态方法允许被子类继承,静态方法只能被静态方法覆盖,但是没有多态的应用

注意:如果在静态方法中访问非静态成员,则可以利用创建对象,用对象名调用非静态的成员。

思考:System.out.println(); 实现原理

 static 可以用于修饰初始化代码块

   (1) 初始化代码块也被称为动态代码块【了解】

   a. 位置:定义在类以内,方法以外

   b. 作用:在创建对象时,按照和属性定义先后顺序,完成对属性的初始化工作。

   对象创建的过程:

   分配空间:为属性赋默认值

   初始化属性:为属性第一次赋值的机会

   执行构造方法:为属性第二次赋值的机会

   (2) 被 static 修饰的初始化代码块称为静态初始化代码块,简称静态代码块。【开发应用重点】

   a. 位置:定义在类以内,方法以外,同时被 static 修饰

   b. 作用:在类加载时,按照和静态属性定义先后顺序,完成对静态属性的初始化工作。

   c. 类加载:

   I. 概念:当 JVM 第一次使用一个类的时候,通过 ClassPath(类路径)找到对应的 class 文件,从 class 文件中读取类的信息(包、类名、父类、属性、成员方法、构造方法等),读取之后将信息存储在 JVM 内存中,一个类只进行一次类加载。

   II. 类加载时机:

 ① 第一次使用该类的静态成员(静态属性和静态方法):会进行类加载
           ② 子类的类加载会导致其父类先进行类加载:先加载其父类,再加载子类
              – 第一次调用子类中的静态成员:先加载其父类,再加载子类
              – 第一次创建子类对象:先加载,再完成对象的创建带有类加载创建对象的过程:

先加载:先加载其父类,再加载子类

先加载父类:为父类的静态属性分配空间并完成父类静态属性的初始化

——> 父类的静态代码块被执行

再加载子类:为子类的静态属性分配空间并完成子类静态属性的初始化

——> 子类的静态代码块被执行

再完成对象的创建:先创建父类对象,再创建子类对象

先完成父类对象的创建:

初始化父类的属性:——> 父类的动态代码块被执行

执行父类的构造方法

再完成子类对象的创建:

初始化子类的属性:——> 子类的动态代码块被执行

执行子类的构造方法

注意:只声明引用不会导致类加载。

4. static 可以用于修饰内部类

♦三、final(最终的、最后的)

1. 变量(局部变量、实例变量、静态变量)

   (1) final修饰的变量是作用范围内的常量,只允许一次赋值,不允许更改,可以多次被使用。

   (2) final的实例变量不再分配默认值,为其初始化的时机:

   a. 声明的同时对其初始化

   b. 在构造方法中对其初始化,但是必须保证每一个构造方法都对其进行初始化

   c. 借助动态代码块对其初始化

   (3) final修饰的静态属性不再分配默认值,为其初始化的时机:

   a. 声明的同时对其初始化

   b. 借助静态初始化代码块对其初始化

注意:final修饰的引用,代表引用中存储对象的地址不能改变。

2. final可以用于修饰方法:可以被子类继承,但是不允许被覆盖。

3. final可以用于修饰类:被final修饰的类不能被继承,即没有子类。

   例如:String / System / Math 等。

⭐接口

♦一、概念

1. 接口:是一种标准、规范,是接口的实现者和接口的使用者都必须遵循的约定。【理解】

2. 接口的语法:

   (1) 接口的关键字: interface

   interface 接口名{}

   (2) 接口编译之后会生成独立的.class文件

   (3) 接口不能创建对象,但是可以声明引用

   (4) 接口中的属性都是公开、静态、常量(默认被 public static final 修饰)

   (5) 接口中的方法都是公开、抽象方法(默认被 public abstract 修饰)

   (6) 接口中没有构造方法

   注意:接口不是类。

♦二、实现类【开发重点】

1. 语法:class 类名 implements 接口名{}

2. 注意:实现类实现接口,如果实现类不想成为抽象类,则需要实现(覆盖)接口中所有的方法;

   实现类实现接口中的方法时,方法的访问修饰符必须是 public 的访问权限。

3. 应用:接口名 引用名 = new 实现类类名(实参);

   注意:接口类型的引用指向实现类的对象,多态的应用。——> 强制使用多态

public class TestInter2{

public static void main(String[] args){

MyInter mi = new MyClass(); // 多态

mi.m1();

int n = mi.m2();

System.out.println(n);

}

}

// 接口

interface MyInter{

int n = 3; // public static final

void m1();

int m2(); // public abstract

}

// 实现类

class MyClass implements MyInter{

public void m1(){

System.out.println("m1的方法…");

}

public int m2(){

System.out.println("m2的方法…");

return 0;

}

}

♦三、接口的继承性【基础重点】

1. Java中的接口之间的继承关系是多继承,一个接口可以有多个父接口

2. 类和接口之间是多实现的关系:一个类可以同时实现多个接口

   (1) 语法:class 类名 implements 接口名1,接口名2{}

   (2) 注意:一个类同时实现多个接口,如果这个类不想成为抽象类,则必须实现所有接口中所有方法;

   而且每一个方法的访问修饰符都是 public

3. 一个类继承一个父类的同时可以实现多个接口

   (1) 语法:class 类名 extends 父类名 implements 接口名1,接口名2{}

   (2) 注意:必须是先继承后实现。(单继承多实现)

♦四、接口多继承的影响【了解】

1. 如果引用之间相互强制类型转换,转换的一方为接口类型的引用,则编译一定通过,但是运行时仍会出现以下两种情况:

   (1) 实际存储的对象类型和要转换的类型一致 -> 成功

   (2) 实际存储的对象类型和要转换的类型不一致 -> 运行报错 java.lang.ClassCastException

(3) 通常将主要功能定义在父类中,次要的功能(扩展的功能)定义在接口中。

♦五、接口的作用[【理解+开发应用】
1.可以扩充子类的能力
(1)由于Java中类之间是单继承,当子类从父类中继承功能方法不足以满足子类功能需求时,可以借助接口扩
充子类的能力
(2)通常将主要功能定义在父类中,次要的功能(扩展的功能)定义在接口中。2. 降低程序中的耦合度

   接口定义好之后,将接口的实现者和接口的使用者分离,借助多态,降低各模块之间的耦合度。

♦六、接口的回调【理解】

1. 接口回调:接口定义之后,先有接口的使用者,再有接口的实现者。

2. 注意:遇到接口回调的应用,开发人员需要关注的是根据接口规范,给予接口的实现部分。

总结:接口和抽象类的区别?【面试重点】

特性 接口 抽象类

关键字 interface abstract class

属性 公开、静态、常量 没有要求(实例变量+静态变量+对final没有要求)

方法 公开、抽象方法 抽象方法+非抽象方法

构造方法 没有 有构造方法

继承关系 多继承 单继承

⭐内部类

♦一、概念

1. 内部类:定义在一个类内部的类。
   ```
   // 外部类
   class Outer{
       // 内部类
       class Inner{}
   }
   ```
2. 内部类编译之后生成独立的 .class 文件,命名:外部类类名$内部类类名.class
3. 内部类可以直接使用外部类私有成员,从而不破坏外部类的封装性。
4. 内部类的分类:成员内部类、静态内部类、局部内部类、匿名内部类。

♦二、内部类的分类

1. 成员内部类:类比于实例变量【了解】
   (1) 位置:定义在类以内,方法以外。
   (2) 成员内部类对象的创建,必须依赖于外部类的对象而创建:
   ```java
   Outer o = new Outer(); // 外部类的对象
   Outer.Inner i = o.new Inner(); // 内部类的对象
   ```
   (3) 访问外部类的当前对象:外部类类名.this
   ```
   外部类类名.this.属性名 – 访问外部类的属性
   外部类类名.this.成员方法名(参数) – 调用外部类的成员方法
   ```
   (4) 成员内部类中不能定义静态成员(静态属性和静态方法)
2. 静态内部类:类比于静态变量【了解】
   (1) 位置:定义在类以内,方法以外,同时被 static 修饰
   (2) 静态内部类中可以定义实例变量,也可以定义静态变量
   (3) 创建静态内部类的对象,只需要依赖于外部类的类名即可:
   ```java
   Outer.Inner i = new Outer.Inner();
   ```
   (4) 访问静态内部类的静态成员时,可以直接通过 外部类类名.静态内部类类名 进行访问:
   ```
   外部类类名.静态内部类类名.静态方法名(实参);
   ```
   (5) 静态内部类只能访问外部类的静态成员(静态属性和静态方法)
3. 局部内部类:类比于局部变量
   (1) 位置:定义在方法内部
   (2) 局部内部类对象的创建,必须在定义它的方法内部创建,并且在类的定义位置后面完成对象的创建
   (3) 局部内部类的方法中可以访问定义它的方法内部的局部变量,但是要求局部变量必须被 final 修饰。
   注意:JDK8.0及以上版本,编译器编译时,如果检测到局部变量被局部内部类中方法访问,则默认为此局部变量前面加 final,这种技术被称为语法糖。
4. 匿名内部类:是一个特殊的局部内部类
   (1) 匿名内部类的定义必须继承一个类或是实现一个接口
   (2) 基于一个匿名内部类只能创建该类的一个对象,并且匿名内部类的定义和对象的创建一起完成。
   (3) 语法:
   ```
   接口名 引用名 = new 接口名() {
       // 接口中需要实现的方法
   };
   ```
   (4) 匿名内部类的优缺点:
   a. 优点:减少代码量,让编程思路连贯。
   b. 缺点:可读性低。

案例:

```java

interface IA{

    void m1();

}

public class Test{

    public static void main(String[] args){

        IA ia = new IA() {

            public void m1(){

                System.out.println("匿名内部类实现的方法…");

            }

        };

        ia.m1();

    }

}

```

```java

public class Test {

    public static void main(String[] args) {

        MyClass mc = new MyClass() {

            public void method(){

                System.out.println("子类覆盖后的方法…");

            }

        };

        mc.method();

    }

}

class MyClass {

    public void method(){

        System.out.println("父类中method方法…");

    }

}

```

赞(0)
未经允许不得转载:171主机测评 » JAVA零基础笔记9,10,11:三个修饰符,接口,内部类
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址