面向对象:内部类,包和导包

本文围绕Java展开,介绍了内部类相关知识,包括局部、成员、静态、私有、匿名内部类的定义、使用及访问方式;阐述了JDK 1.8新特性lambda表达式,用于简化匿名内部类对象;还讲解了包和导包,如创建包的原因、方法,以及导包的作用和规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内部类

  • 局部内部类 (定义在方法中)

定义在方法中,内部类为局部内部类

局部内部类中只能定义非静态的成员内容,除了静态的常量
在局部内部类中可以使用所在外部类的成员
局部内部类中如果一旦使用所在方法的局部变量(参数),这个局部变量必须为常量
    jdk7及之前 : 要求必须手动被final修饰
    jdk8及之后 : 默认被final修饰
只能在所在的方法中通过对象访问局部内部类的成员,在外部类中的其他方法中|其他类中都无法使用局部内部类
public class Test01 {
    public static void main(String[] args) {
        class A{
            int n;
            public A(){}
            public void m(){
                System.out.println("我是局部内部类的一个m方法");
            }
        }
​
        // 后续使用
        A a = new A();
        a.m();
    }
}
  • 成员内部类 (定义在类中)

    • 外部类使用内部类

      • 创建对象 直接调用

    • 内部类使用外部类

      • 直接使用 内部类都会持有一个外部类对象的引用(外部类.this)

    • 其他类使用外部类

      • 一般不允许,所以我们会将内部类私有 防止外部访问

      • 创建外部类对象.创建内部类对象 然后访问

      • 外部类.内部类  变量 = new 外部类().new 内部类();
内部类定义在外部类的成员位置

可以被成员修饰符所修饰,可以继承其他父类,实现需要的接口,具有成员的特点,具有类的特点

特点 :
    在成员内部类中只能定义非静态的成员内容,除了静态的常量
    在成员内部类中可以直接使用所在外部类的成员,包括私有的
    在所在外部类中需要通过成员内部类的对象访问其成员(包括私有成员),可以通过类名访问其静态的常量
    在其他类中需要 通过外部类创建成员内部类对象,通过成员内部类对象访问其成员
package com.yjxxt.oop.inner;
​
public class Test02 {
    public static void main(String[] args) {
       /* Outer01 outer01 = new Outer01();
        outer01.m();*/
​
        Outer01 outer01 = new Outer01();
        System.out.println(outer01.n);
​
        /*Outer01.Inner01 inner01 = outer01.new Inner01();
        inner01.fun();*/
    }
}
​
class Outer01{
    int n;
    public void m(){
        System.out.println("outer01 m");
        System.out.println(this.n);
        Inner01 inner01 = new Inner01();
        inner01.fun();
    }
​
    private class Inner01{
        int m;
        public void fun(){
            System.out.println("inner01 fun");
            System.out.println(/*Outer01.this.*/n);
​
        }
    }
}
  • 静态内部类 (定义在类中 静态类)

  • 外部类使用静态内部类

    • 如果访问的是静态内部类中的静态内容: 类名.静态内容

    • 如果访问的是静态内部类中的非静态内容: 创建对象访问

  • 内部类使用外部类

    • 创建对象访问

  • 其他类使用外部类

    • 一般不允许,所以我们会将内部类私有 防止外部访问

    • 创建外部类对象.创建内部类对象 然后访问

      外部类.内部类  变量 = new 外部类().new 内部类();
被static修饰的内部类

静态内部类中可以根据需求定义静态|非静态的成员
在静态内部类中可以直接使用所在外部类的静态内容,需要通过外部类的对象访问其成员
在所在外部类中可以通过类名访问静态内部类中静态内容,需要通过对象访问静态内部类中的成员
在其他类中可以通过外部类类名.内部类类名.静态内容访问静态内部类中的静态内容
在其他类中可以通过new 外部类类名.内部类类名()的内部类对象访问静态内部类中的成员内容
package com.yjxxt.oop.inner;
​
public class Test03 {
    public static void main(String[] args) {
       /* Outer02 outer02 = new Outer02();
        outer02.fun();*/
​
​
        // Outer02.Inner02.m();
​
       // new Outer02.Inner02();
​
        System.out.println(Outer02.m);
​
      /*  Outer02.Inner02 inner02 = new Outer02.Inner02();
        System.out.println(inner02.n);*/
        
       
​
    }
}
​
class Outer02{
​
    static int m;
    public void fun(){
        System.out.println("outer fun");
​
        // 如何使用内部类中的内容
        System.out.println(m);
        Inner02 inner02 = new Inner02();
        System.out.println(inner02.n);
        Inner02.m();
    }
​
    static class Inner02{
        int n;
​
        public void method(){
            System.out.println("inner method");
            new Outer02().fun();
            
            
        }
        public static void m(){
            System.out.println("inner m");
            
            
        }
​
    }
​
}

  

    私有内部类 :


    被private修饰的成员内部类
    私有内部类中可以直接使用外部类的成员,包括私有的
    在所在外部类中,通过私有内部类的对象访问其成员
    其他类中无法使用私有内部类

  • 匿名内部类 (定义在方法中)

简化一些满足条件要求的实现类|子类,将定义实现类重写方法+创建实现类对象两步合并成一步
    1)类没有自己本身作用
    2)实现类|子类只在当前使用一次,不会重复使用多次

语法 :
    new 接口|抽象类(){--->实现类|子类类体
        重写方法....
    };
public class Class006_Outer {
    public static void main(String[] args) {
        //定义接口实现类
        //Demo demo = new Demo();
        //demo.swimming();

        //匿名内部类对象使用方式一 : 匿名对象-->对象只能在当前使用一次
        new Swim(){
            @Override
            public void swimming() {
                System.out.println("花样游泳....");
            }
        }.swimming();

        //匿名内部类对象的使用方式二 : 引用指向对象
        AbsClass abs = new AbsClass(){
            @Override
            void absMethod(boolean flag) {
                System.out.println("抽象类的子类"+flag);
            }
        };
        abs.absMethod(false);
        abs.absMethod(true);

        //匿名内部类使用方式三 : 作为方法的实参
        testSwim(new Swim() {
            @Override
            public void swimming() {
                System.out.println("仰泳...");
            }
        });

    }
    //游泳俱乐部,入场的都要会游泳的
    public static void testSwim(Swim swim){  //当方法的形参为一个接口类型,方法的实参就要为接口的实现类对象
        swim.swimming();
    }
}
//接口
interface Swim{
    void swimming();
}

//实现类
class Demo implements Swim{

    @Override
    public void swimming() {
        System.out.println("狗刨....");
    }

}

abstract class AbsClass{
    abstract void absMethod(boolean flag);
}

lambda表达式 : *****

jdk1.8新特性之一

    作用 : 简化满足条件的匿名内部类对象
    前提 : 函数式接口

    函数式接口 : 抽象方法只有一个
    如何检查一个接口是否为函数式接口 : @FunctionalInterface

    语法 :
        ()->{}
        () : 重写方法的参数列表
        -> : 箭头函数  |  lambda符号
        {} : lambda体-->重写方法的方法体

    注意 :
        以后看到方法的形参|引用的引用的类型为函数式接口的时候,那么传递实参|为引用赋值就可以通过lambda表达式进行实现

public class Class001_Lambda {
    public static void main(String[] args) {
        //匿名内部类对象
        /*Smoke s = new Smoke(){
            @Override
            public void smoking() {
                System.out.println(".....");
            }
        };*/

        //lambda 写法1 : 标准写法
        /*Smoke s = () -> {
            System.out.println(".....");
        };*/

        //lambda 写法2 : 当lambda体中语句只有一句,前后的{}可以省略
        //Smoke s = () -> System.out.println("边抽烟会吐烟圈...");


        //lambda 写法3 : 当抽象方法存在参数,参数的数据类型可以省略
        //Smoke s = (name,age) -> System.out.println("边抽烟会吐烟圈..."+age);


        //lambda 写法4 : 当抽象方法存在参数且参数只有一个,前后的()可以省略
        //Smoke s = a -> System.out.println("边抽烟会吐烟圈..."+a);


        //lambda 写法5 : 当抽象方法存在返回值,lambda体中语句只有一句,且是return带出返回值语句,前后的{}与return关键字可以一起省略
        //Smoke s = age -> age>=18;

        //System.out.println(s.smoking(19));;

        testSmoke(new Smoke() {
            @Override
            public boolean smoking(int age) {
                return false;
            }
        });

        testSmoke(age->age>=18);  //函数式编程
        //将方法的实现作为参数传递
    }

    static void testSmoke(Smoke smoke){
        smoke.smoking(20);
    }
}

//接口
@FunctionalInterface
interface Smoke{
    boolean smoking(int age);

    //静态方法
    static void testStatic(){}
    default void testDefault(){}
}

包和导包

package com.yjxxt.oop.ext; // 通过package指定当前类所属的包 这行代码一定是一个类的首行

1: 为什么需要创建包? 为什么在创建类的时候需要给当前类指定包?

区分不同的类,管理不同的类。

2:如何创建一个包?

详细请看标识符。  
一般命名规则: 公司域名倒着写  com.yjxxt 
项目名称: 学生管理系统 .ss  
模块名称: 学生模块  .student
子模块名称... 
com.yjxxt.ss.student.view.....

3: 如何确定一个类?

确定类的方式: 全限定名  包名.类名   com.yjxxt.oop.ext.Test02  

导包

导包就是为了使用类。在使用类的时候需要通过包名.类名去确定。

  • java.lang包下的所有类是不需要导入的

  • jdk1.7之后支持静态导入,可以不需要写类名,直接使用方法或者是变量。

    import static 包名.类名.*;  // 导入指定包下的指定类中的所有静态内容
  • 如果需要导入同名类,此时一个通过导入的方式,一个需要通过全限定名去使用。

    import java.util.Date;
    main(){
        Date d = new Date(); // java.util.Date
        java.sql.Date date = new java.sql.Date(1L); 
    }
    权限修饰符/位置本类同包子类同包异类异包子类异包异类
    public
    protected×
    默认的 不写××
    private××××

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值