day15 抽象类&接口&内部类

第一章 抽象类

1.1 概述

1.1.1 抽象类引入

**我们把没有方法体的方法称为抽象方法。

  • 抽象方法 : 没有方法体的方法。

  • 抽象类:包含抽象方法的类。

1.2.1 抽象方法

使用abstract 关键字修饰方法,该方法就成了抽象方法,抽象方法只包含一个方法名,而没有方法体。

定义格式:

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

1.2.2 抽象类

抽象类不一定有抽象方法,但是有抽象方法的类必须定义成抽象类。

定义格式:

 abstract class 类名字 { 
 }

代码举例:

public abstract class Animal {
     public abstract void run();
 }

1.2.3 抽象类的使用

要求:继承抽象类的子类必须重写父类所有的抽象方法。否则,该子类也必须声明为抽象类。

方法重写,是子类对父类抽象方法的完成实现,我们将这种方法重写的操作,也叫做实现方法

1.5 抽象类存在的意义

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

第二章 接口

2.1 概述

接口是更加彻底的抽象,JDK7之前,包括JDK7,接口中全部是抽象方法。接口同样是不能创建对象的

2.2 定义格式

 //接口的定义格式:
 interface 接口名称{
     // 抽象方法
 }
 ​
 // 接口的声明:interface
 // 接口名称:首字母大写,满足“驼峰模式”

2.3.1.抽象方法

注意:接口中的抽象方法默认会自动加上public abstract修饰程序员无需自己手写!!

 public interface InterF {
     // 抽象方法!
     //    public abstract void run();
     void run();
 ​
     //    public abstract String getName();
     String getName();
 ​
     //    public abstract int add(int a , int b);
     int add(int a , int b);
 }

2.4 基本的实现

2.4.1 实现接口的概述

实现使用 implements关键字。

2.4.2 实现接口的格式

 /**接口的实现:
     在Java中接口是被实现的,实现接口的类称为实现类。
     实现类的格式:*/
 class 类名 implements 接口1,接口2,接口3...{
 ​
 }

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

  1. 必须重写实现的全部接口中所有抽象方法。

  2. 如果一个类实现了接口,但是没有重写完全部接口的全部抽象方法,这个类也必须定义成抽象类。

  3. 意义:接口体现的是一种规范,接口对实现类是一种强制性的约束,要么全部完成接口申明的功能,要么自己也定义成抽象类。这正是一种强制性的规范。

2.4.4 类与接口基本实现案例

假如我们定义一个运动员的接口(规范),代码如下:

 /**
    接口:接口体现的是规范。
  * */
 public interface SportMan {
     void run(); // 抽象方法,跑步。
     void law(); // 抽象方法,遵守法律。
     String compittion(String project);  // 抽象方法,比赛。
 }

接下来定义一个乒乓球运动员类,实现接口,实现接口的实现类代码如下:

 package com.itheima._03接口的实现;
 /**
  * 接口的实现:
  *    在Java中接口是被实现的,实现接口的类称为实现类。
  *    实现类的格式:
  *      class 类名 implements 接口1,接口2,接口3...{
  *
  *
  *      }
  * */
 public class PingPongMan  implements SportMan {
     @Override
     public void run() {
         System.out.println("乒乓球运动员稍微跑一下!!");
     }
 ​
     @Override
     public void law() {
         System.out.println("乒乓球运动员守法!");
     }
 ​
     @Override
     public String compittion(String project) {
         return "参加"+project+"得金牌!";
     }
 }

测试代码

 public class TestMain {
     public static void main(String[] args) {
         // 创建实现类对象。
         PingPongMan zjk = new PingPongMan();
         zjk.run();
         zjk.law();
         System.out.println(zjk.compittion("全球乒乓球比赛"));
 ​
     }
 }

2.4.5 类与接口的多实现案例

类与接口之间的关系是多实现的,一个类可以同时实现多个接口。

2.5 接口与接口的多继承

Java中,接口与接口之间是可以多继承的:也就是一个接口可以同时继承多个接口。大家一定要注意:

类与接口是实现关系

接口与接口是继承关系

案例演示:

 public interface Abc {
     void go();
     void test();
 }
 ​
 /** 法律规范:接口*/
 public interface Law {
     void rule();
     void test();
 }
 ​
  *
  *  总结:
  *     接口与类之间是多实现的。
  *     接口与接口之间是多继承的。
  * */
 public interface SportMan extends Law , Abc {
     void run();
 }

第三章 内部类

3.1.1 什么是内部类

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

3.1.2 什么时候使用内部类

一个事物内部还有一个独立的事物,内部的事物脱离外部的事物无法独立使用

  1. 人里面有一颗心脏。

  2. 汽车内部有一个发动机。

  3. 为了实现更好的封装性。

3.2 内部类的分类

按定义的位置来分

  1. 成员内部内,类定义在了成员位置 (类中方法外称为成员位置,无static修饰的内部类)

  2. 静态内部类,类定义在了成员位置 (类中方法外称为成员位置,有static修饰的内部类)

  3. 局部内部类,类定义在方法内

  4. 匿名内部类,没有名字的内部类,可以在方法中,也可以在类中方法外。

3.3 成员内部类

成员内部类特点

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

  • 宿主:外部类对象。

内部类的使用格式

  外部类.内部类。

获取成员内部类对象的两种方式

方式一:外部直接创建成员内部类的对象

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

方式二:在外部类中定义一个方法提供内部类的对象

案例演示

 方式一:
 public class Test {
     public static void main(String[] args) {
         //  宿主:外部类对象。
        // Outer out = new Outer();
         // 创建内部类对象。
         Outer.Inner oi = new Outer().new Inner();
         oi.method();
     }
 }
 ​
 class Outer {
     // 成员内部类,属于外部类对象的。
     // 拓展:成员内部类不能定义静态成员。
     public class Inner{
         // 这里面的东西与类是完全一样的。
         public void method(){
             System.out.println("内部类中的方法被调用了");
         }
     }
 }
 
 方式二:
 public class Outer {
     String name;
     private class Inner{
         static int a = 10;
     }
     public Inner getInstance(){
         return new Inner();
     }
 }
 ​
 public class Test {
     public static void main(String[] args) {
         Outer o = new Outer();
         System.out.println(o.getInstance());
     }
 }

3.4 成员内部类的细节

详解:

内部类被private修饰,外界无法直接获取内部类的对象,只能通过3.3节中的方式二获取内部类的对象

被其他权限修饰符修饰的内部类一般用3.3节中的方式一直接获取内部类的对象

3.5 成员内部类面试题

请在?地方向上相应代码,以达到输出的内容

注意:内部类访问外部类对象的格式是:外部类名.this

 public class Test {
     public static void main(String[] args) {
         Outer.inner oi = new Outer().new inner();
         oi.method();
     }
 }
 ​
 class Outer {   // 外部类
     private int a = 30;
 ​
     // 在成员位置定义一个类
     class inner {
         private int a = 20;
 ​
         public void method() {
             int a = 10;
             System.out.println(???);    // 10   答案:a
             System.out.println(???);    // 20   答案:this.a
             System.out.println(???);    // 30   答案:Outer.this.a
         }
     }
 }

3.7 静态内部类

静态内部类特点

  • 静态内部类是一种特殊的成员内部类。

  • 有static修饰,属于外部类本身的。

  • 总结:静态内部类与其他类的用法完全一样。只是访问的时候需要加上外部类.内部类。

  • 拓展1:静态内部类可以直接访问外部类的静态成员。

  • 拓展2:静态内部类不可以直接访问外部类的非静态成员,如果要访问需要创建外部类的对象。

  • 拓展3:静态内部类中没有银行的Outer.this。

内部类的使用格式

调用方法的格式:

  • 调用非静态方法的格式:先创建对象,用对象调用

  • 调用静态方法的格式:外部类名.内部类名.方法名();

案例演示

 public class InnerClassDemo01 {
     public static void main(String[] args) {
         // 创建静态内部类对象。
         // 外部类.内部类  变量 = new  外部类.内部类构造器;
         Outer01.Inner01 in  = new Outer01.Inner01("张三");
         in.showName();
     }
 }

3.8 局部内部类

  • 局部内部类 :定义在方法中的类。

定义格式:

 class 外部类名 {
     数据类型 变量名;
      
     修饰符 返回值类型 方法名(参数列表) {
         // …
         class 内部类 {
             // 成员变量
             // 成员方法
         }
     }
 }

3.9 匿名内部类【重点】

3.9.1 概述

匿名内部类 :是内部类的简化写法。他是一个隐含了名字的内部类。开发中,最常用到的内部类就是匿名内部类了。

3.9.2 格式

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

包含了:

  • 继承或者实现关系

  • 方法重写

  • 创建对象

所以从语法上来讲,这个整体其实是匿名内部类对象

3.9.2 什么时候用到匿名内部类

实际上,如果我们希望定义一个只要使用一次的类,就可考虑使用匿名内部类。匿名内部类的本质作用

是为了简化代码

之前我们使用接口时,似乎得做如下几步操作:

  1. 定义子类

  2. 重写接口中的方法

  3. 创建子类对象

  4. 调用重写后的方法

 interface Swim {
     public abstract void swimming();
 }
 ​
 // 1. 定义接口的实现类
 class Student implements Swim {
     // 2. 重写抽象方法
     @Override
     public void swimming() {
         System.out.println("狗刨式...");
     }
 }
 ​
 public class Test {
     public static void main(String[] args) {
         // 3. 创建实现类对象
         Student s = new Student();
         // 4. 调用方法
         s.swimming();
     }
 }

我们的目的,最终只是为了调用方法,那么能不能简化一下,把以上四步合成一步呢?匿名内部类就是做这样的快捷方式。

3.9.3 匿名内部类前提和格式

匿名内部类必须继承一个父类或者实现一个父接口

匿名内部类格式

new 父类名或者接口名(){
     // 方法重写
     @Override 
     public void method() {
         // 执行语句
     }
 };

3.9.4 使用方式

以接口为例,匿名内部类的使用,代码如下:

 interface Swim {
     public abstract void swimming();
 }
 ​
 public class Demo07 {
     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();
         s2.swimming();
     }
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值