首页 > 编程语言 >Java学习笔记10

Java学习笔记10

时间:2023-01-14 11:11:45浏览次数:44  
标签:10 Java 内部 接口 笔记 new 抽象类 方法 public

1. 抽象类

1.1 概述

​ 没有方法体的方法称为抽象方法。Java语法规定,包含抽象方法的类就是抽象类。

  • 抽象方法:没有方法体的方法。
  • 抽象类:包含抽象方法的类。

1.2 abstract

abstract用于修饰抽象方法和抽象类。

1.2.1 抽象方法

使用abstract关键字修饰的方法就是抽象方法,抽象方法只有方法名,没有方法体。

定义格式:

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

1.2.2 抽象类

​ 如果一个类包含抽象方法,则该类必须为抽象类。

注意:抽象类不一定有抽象方法,但是有抽象方法的类必须定义为抽象类。

定义格式:

abstract class 类名 {
    
}

注意:抽象类的子类必须重写父类中所有的抽象方法,否则,子类也要定义为抽象类。

1.3 抽象类的特征

​ 抽象类的特征可以概括为有得有失

  • 有得:抽象类得到了拥有抽象方法的能力。
  • 有失:抽象类失去了创建对象的能力。

1.4 抽象类存在的意义

​ 抽象类存在的意义是为了被子类继承,否则抽象类将毫无意义。抽象类可以强制子类按照规定的格式进行重写。

2. 接口

2.1 概述

​ 接口是更加彻底的抽象,JDK8之前,接口中全部是抽象方法。接口和抽象类一样不能创建对象(实例化)。

定义格式:

interface 接口名 {
    
}

JDK8之前,接口中只含有抽象方法和常量。

  • 抽象方法:接口中的抽象方法默认用public abstract修饰。
  • 常量:接口中的成员变量默认用public static final修饰,也就是说在接口中定义的成员变量实际上是常量。

2.2 接口的实现

2.2.1 概述

​ 类与接口的关系为实现关系,即类实现接口。实现类似继承,使用implements关键字。

格式:

class 类名 implements 接口1, 接口2, 接口3... {
    
}

2.2.2 类实现接口的要求和意义

要求:

  • 必须重写全部接口中的所有抽象方法。
  • 如果一个类实现了接口,但是没有重写全部的抽象方法,这个类必须定义为抽象类。

意义:接口体现的是一种规范,接口对实现类是一种强制性的约束。

2.3 接口与接口的多继承

​ Java中,接口之间是可以多继承的。

注意:

  • 类与接口是实现关系。
  • 接口与接口是继承关系。

2.4 接口的细节

  • 两个接口中存在相同的抽象方法时,只需要重写一次。

  • 父类和实现的接口中有相同的方法时:

    • 如果父类中的方法体能满足当前业务的需求,子类中可以不用重写。
    • 如果父类中的方法体不能满足当前业务的需求,需要在子类中重写。
  • 如果接口有多个抽象方法,但是实现类中只需要用其中一小部分时,可以采用适配器设计模式:

    • 可以在接口和实现类中新建一个中间类(适配器类),让适配器类实现接口,对接口里面所有的方法做空重写,然后让实现类继承适配器类,需要用到什么方法就在实现类中重写什么方法。

3. 内部类

3.1 概述

​ 在类A里面定义类B,类B就称为内部类,类A称为外部类。

​ 一个事物内部还有一个独立的事物,但是内部的事物脱离外部的事物独立存在没有意义,这个时候就可以使用内部类。

3.2 分类

内部类可以分为:

  1. 成员内部类:定义在成员位置(无static修饰)。
  2. 静态内部类:定义在成员位置且有static修饰。
  3. 局部内部类:定义在方法内。
  4. 匿名内部类:没有名字的内部类,可以定义在方法中,也可以定义在类中方法外。

3.3 成员内部类

特点:

  • static修饰,属于外部类对象。

获取成员内部类对象:

  • 方法一:外部直接创建成员内部类的对象(内部类没有被private修饰)

    格式:
    外部类.内部类 变量名 = new 外部类().new 内部类();
    示例:
    public class Test {
        public static void main(String[] args) {
            Outer.Inner oi = new Outer().new Inner();
            oi.method();
        }
    }
    
    public class Outer {
        public class Inner {
            public void method() {
                System.out.println("内部类中的方法被调用了");
            }
        }
    }
    
  • 方法二:在外部类中定义一个方法提供内部类的对象(内部类被private修饰)

    示例:
    public class Test {
        public static void main(String[] args) {
            Outer o = new Outer();
            0.getInstance().method();
        }
    }
    
    public class Outer {
        private class Inner {
            
        }
        
        public Inner getInstance() {
            return new Inner();
        }
    }
    

注意:

  • 成员内部类可以被一些修饰符修饰,比如:privateprotectedpublicstatic和默认等。
  • 在JDK16以前,成员内部类里面不能定义静态变量。
  • 创建内部类对象时,对象中有一个隐含的Outer.this记录外部类对象的地址值。

扩展:

public class Test {
    public static void main(String[] args) {
        Outer.Inner oi = new Outer().new Inner();
        oi.show();
    }
}

public class Outer {
    private int a = 10;
    public class Inner {
        private int a = 20;
        
        public void show() {
            int a = 30;
            System.out.println(Outer.this.a); // 10
            System.out.println(this.a); // 20
            System.out.println(a); // 30
        }
    }
}

3.4 静态内部类

特点:

  • 静态内部类是一种特殊的成员内部类。
  • static修饰,属于外部类本身。
  • 静态内部类与其他类的用法完全一致,只是格式不同。
  • 静态内部类可以直接访问外部类的静态成员。
  • 静态内部类不可以直接访问外部类的非静态成员,必须创建外部类的对象后才能访问。
  • 静态内部类中没有隐含的Outer.this

格式:

外部类.内部类

静态内部类对象的创建格式:

外部类.内部类 变量名 = new 外部类.内部类();

3.5 局部内部类

​ 在方法中定义的类叫做局部内部类。

定义格式:

class 外部类 {
    修饰符 返回值 方法名(参数列表) {
        class 内部类 {
        
    	}
    }
}

3.6 匿名内部类(重点)

3.6.1 概述

​ 匿名内部类是内部类的简化写法,是一个隐含了名字的内部类。

格式:

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

其中包含了:

  • 继承或者实现关系
  • 方法重写
  • 创建对象

从语法上来讲,这个整体是匿名内部类的对象,匿名内部类是大括号里面的内容。

3.6.2 匿名内部类的使用

使用时机:如果一个类只使用一次,就可以考虑使用匿名内部类。

使用前提:匿名内部类必须继承一个父类或者实现一个接口。

示例1:

public interface Swim {
    public abstract void swimming();
}

public class Test {
    public static void main(String[] args) {
        // 使用匿名内部类
		new Swim() {
			@Override
			public void swimming() {
				System.out.println("自由泳...");
			}
		}.swimming();

        // 接口 变量 = new 实现类(); // 多态,走子类的重写方法
        Swim s2 = new Swim() {
            @Override
            public void swimming() {
                System.out.println("蛙泳...");
            }
        };

        s2.swimming();
    }
}

示例2:

public interface Swim {
    public abstract void swimming();
}

public class Test {
    public static void main(String[] args) {
        // 普通方式传入对象
        // 创建实现类对象
        Student s = new Student();
        
        goSwimming(s);
        // 匿名内部类使用场景:作为方法参数传递
        Swim s3 = new Swim() {
            @Override
            public void swimming() {
                System.out.println("蝶泳...");
            }
        };
        // 传入匿名内部类
        goSwimming(s3);

        // 完美方案: 一步到位
        goSwimming(new Swim() {
            public void swimming() {
                System.out.println("大学生, 蛙泳...");
            }
        });

        goSwimming(new Swim() {
            public void swimming() {
                System.out.println("小学生, 自由泳...");
            }
        });
    }

    public static void goSwimming(Swim s) {
        s.swimming();
    }
}

标签:10,Java,内部,接口,笔记,new,抽象类,方法,public
From: https://www.cnblogs.com/kuaicode/p/17051460.html

相关文章