Java入门 第十一节 内部类

本文详细介绍了Java内部类的四种类型:成员内部类、局部内部类、静态内部类和匿名内部类,强调了它们的特点和访问方式。通过实例展示了如何使用内部类实现多继承的效果,探讨了内部类在封装性和访问权限上的优势。此外,还讨论了静态内部类的使用场景和访问外部类成员的规则。
摘要由CSDN通过智能技术生成

内部类

1. 什么是内部类 ?

  1. 简单理解,就是在一个类中 定义 另一个类。
    • 如: class A 中定义class B。 B 就是所谓的内部类。

1.1 语法定义

  1. 定义位置 来说: 外面的叫外部类,里面的叫内部类,就相对而言。
	// 外部类
	修饰符 class 类名{
	
	    //在类的内部定义的类叫做内部类。
	    修饰符  class  类名{
	
	    }
	}

1.2 内部类分类

  1. 分为四种:
    • 成员内部类: 定义在成员位置,类中方法外。
    • 局部内部类 :在局部位置 (即方法中)
    • 静态内部类: 被关键字static 修饰的内部类。
    • 匿名内部类: 同匿名对象一样,没有名字,只为了调用一次。

1.3 内部类的特点

  1. 一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
  2. 内部类不为同一包的其他类所见,具有很好的封装性;
  3. 内部类有效实现了“多重继承”,优化 java 单继承的缺陷。

2. 内,外部类之间的访问方式

  1. 一个内部类对象,可以访问创建它的外部类对象的内容,包括私有数据!
  2. 内外可以相互访问:
    • 内部类 ,可以直接访问,外部类中的 成员变量和方法,包括 private修饰的成员。
    • 外部类,如果想访问内部类成员,就必须建立内部类的对象。

2.1 访问方式一(提倡)

  1. 外部类访问内部类,需要在外部类的方法中,创建内部类的对象, 来访问内部类。
	public class MyClass {
	    public static void main(String[] args) {
	        OutClass o = new OutClass();
	        o.method();
	    }
	}
	
	//相对内部类来说,
	class OutClass{//外部类
	    private String name="OutClass";//私有属性
	
	    private void test(){
	        System.out.println("外部类方法");
	    }
	
	    //相对外部类来说
	    class InterClass{ //内部类,可以使用private修饰
	
	        public void show(){
	            System.out.println(name);// 访问外部类的私有属性
	            test(); //也可以访问外部类私有方法
	        }
	
	    }
	
	    /*
	        访问方式一: 通过外部类方法,创建内部类对象访问
	     */
	    public void method(){
	        InterClass i = new InterClass();
	        i.show();
	    }
	}

  • 输出结果:

    	OutClass
    	外部类方法
    

2.1 访问方式二(了解)

  1. 通过类调用直接访问。

    • 访问方式: 外部类.内部类 变量名 = 外部对象.内部对象 ;
    • 注意: 内部类不能使用 private 修饰。
    public class MyClass {
        public static void main(String[] args) {
            //访问方式二: 外部类.内部类 变量名 = 外部类对象.内部类对象;
            //前提需要注意: 不能被
           OutClass.InterClass oi = new OutClass().new InterClass();
           oi.show();
    
        }
    }
    
    //相对内部类来说,
    class OutClass{//外部类
        private String name="OutClass";//私有属性
    
        private void test(){
            System.out.println("外部类方法");
        }
    
        //相对外部类来说
         class InterClass{ //如果使用 外内结合对象的方式访问 内部类不能使用private修饰。
            public void show(){
                System.out.println(name);// 访问外部类的私有属性
                test(); //也可以访问外部类私有方法
            }
    
        }
    }
    
    
  • 输出结果:

    	OutClass
    	外部类方法
    

3. 成员内部类

3.1 private修饰内部类

  1. 内部类不为同一包的其他类所见,具有很好的封装性;

  2. 内部类被private修饰,目的,就是 隐藏自己(封装) 不想被外界发现或者使用!

  3. 例如生活中:

    • 人类,最重要的器官就是心脏,心脏就需要心跳。当心脏问题时,只能交给专业的人去治疗。
    
    public class MyClass {
        public static void main(String[] args) {
            //1. 如果内部类使用了private修饰,访问方式就使用第一种
            // 外部类创建方法调用内部类对象。
            Person p = new Person();
            p.make_Heart("荒漠屠夫");
        }
    }
    
    class Person{
    
        //2.为啥要私有?这样就可以封装起来
        private class Heart{
            //内部类就一个方法,心跳方法
            private void heartbeat(){
                //很复杂的业务处理机制...
                System.out.println("心脏在跳动... ");
            }
        }
    
    
        //2.心脏真出问题了需要治疗,
        // 意思: 提供一个访问内部类方法
        public void make_Heart(String name){
            //通过if判断控制
            if (name.equals("医生")){
                new Heart().heartbeat();//创建内部类对象,访问内部类方法
            }else {
                System.out.println("不符合条件");
            }
        }
    
    }
    
  • 输出结果:

    不符合条件
    

3.2 静态内部类

3.2.1 定义
  1. 被关键字 static修饰内部类,就是静态内部类,并且static只能修饰内部类。

  2. 静态内部类 和 普通内部类的区别:

    • 普通内部类 :不允许有静态属性和静态方法;
    • 静态内部类: 可以声明普通成员变量 和 方法。但是静态内部类中,
  3. 普通方法访问不了外部类属性,因为需要将 静态内部类中所有,看做一个整体。

    • 这样就需要遵循static 特点,静态只能访问静态。
        public static void main(String[] args) {
    
            //第二种访问方式,没有private修饰。
            Person.Heart ph = new Person.Heart();// 静态的访问方式
            ph.heartbeat();
    
        }
    }
    
    class Person{
        private  int num=60; //外部类成员属性
    		//1.静态内部类中的普通方法!为啥访问不了外部类属性!?
            //解答:相当于把静态内部类看成一个整体,这样访问外部属性的时候,也需要遵循静态访问静态的原则。
            // 但是内部成员来说,还是遵守static 关键字的使用!!!
       public class MyClass {
        //内部类
        static class Heart{ //static 静态内部类
            public void heartbeat(){ //静态类中可以有普通方法
                System.out.println("每分钟跳"+num); //获取外部类属性?
            }
        }
    }
    
  • 输出结果:

    Error:(23, 42) java: 无法从静态上下文中引用非静态 变量 name
    
3.2.1 静态内部类访问方法和属性
  1. 必须把static 修饰的内部类看做一个整体,遵循 static访问特点,
    • 静态只能访问静态。
    • 非静态可以访问静态和非静态。
    public class MyClass {
        public static void main(String[] args) {
            //1. 如果内部类使用了private修饰,访问方式就使用第一种
            // 外部类创建方法调用内部类对象。
            Person p = new Person();
            p.make_Heart("医生");
    
    		//2. 没有被private 修饰内部类 
    		new Person.Heart().heartbeat();//如可以使用链式访问
        }
    }
    
    class Person{
    
        private int num=60;
        static String speed="20秒";
    
    
        //2.为啥要私有?这样就可以封装起来
        static class Heart{
    
            //内部类就一个方法,心跳方法
            public void heartbeat(){
                //静态中的普通方法也可以静态属性
                System.out.println("心脏在跳动... "+speed);
            }
    
            static void blood(){
                System.out.println("血液开始流动,每 "+speed+" 循环一次"); //静态方法调用静态属性
            }
        }
    
    
    
        public void make_Heart(String name){
    
            if (name.equals("医生")){
                Heart h = new Heart();
                h.heartbeat();
                h.blood(); // 调用静态
            }else {
                System.out.println("不符合条件");
            }
        }
    
    }
    
    
  • 输出结果:

    	心脏在跳动... 20秒
    	血液开始流动,每 20秒 循环一次
    

4. 局部内部类(了解即可)

  1. 在方法里的类。不常见
    • 该内部类权限必须是 public
public class MyClass {
    public static void main(String[] args) {

        new Person().heartbeat();//调用外部类方法,在通过方法调用内部类方法

    }
}

class Person{

        public void heartbeat(){

            //在方法中的内部类,权限就是 public
             class Blood{
                public void speed(){
                    System.out.println("在心脏中的血液... ");
                }
            }

            //使用匿名对象,调用一次内部类
            new Blood().speed();
        }

}

5. 匿名内部类

  1. 匿名对象 一样,没有名字 的内部类。就是为了调用一次。

  2. 语法结构:

    	new 接口/类名(){ //需要花括号
    		  1.重写方法
    		  2.自定义方法
    	};
    
  3. 匿名对象和匿名内部类通常一起使用,属于局部内部类

public class MyClass2 {
    public static void main(String[] args) {
        Person2 p = new Person2();
        p.heart();
        p.blood();
    }
}


class Person2{

    //调用接口
    public void heart(){
        //1. 匿名内部类调用接口
        new Make(
        ) {
            @Override
            public void heartbeat(String name) {
                if (name.equals("医生")){
                    System.out.println("请开始手术");
                }else {
                    System.out.println("需要医生");
                }
            }
        }.heartbeat("医生"); //相当于调用方法传递参数。
    }

    //2.调用普通方法
    public void blood(){
        //普通类也能调用。但是需要手动重写方法
        new Make2(){
            @Override
            public void blood() {
                System.out.println("血液流动中.....");
            }
        }.blood();
    }
}


//1.接口
interface  Make{
    public abstract void heartbeat(String name);//治疗薪资
}
//2.普通方法
 class Make2{
    public void blood(){
        System.out.println("血液流动");
    }
}
//3.抽象类,自己动手

6 使用内部类实现“多继承”。

  1. 内部类有效实现了 “多重继承” ,优化 java 单继承的缺陷。
    • 例如:手艺的传承,爷爷会一种,爸爸会一种, 儿子正常来说应该会两种。
public class MyClass {
    public static void main(String[] args) {

        Son son = new Son();
        son.doThing();


        //1. 调用爷爷的方法
        Son.Myself sm = new Son().new Myself();
        sm.doThing();//调用爷爷的。

        //1.使用多态形
        Person.method(new Father()); //静态方法类名直接调用


    }
}

interface Person{
    public void doThing();

    //查看会什么功能。
    static void method(Person p){
        p.doThing();
    }
}

class Grandpa implements Person{
    public void doThing(){
        System.out.println("会开摩托车");
    }
}

class Father implements Person{
    public void doThing(){
        System.out.println("会开汽车");
    }
}

//Son类能继承Father类和Grandpa类么?
class Son extends Father{
    //1.使用内部类实现爷爷的方法
     class Myself extends Grandpa {
        @Override
        public void doThing() {
            super.doThing(); //调用他爷爷的方法
        }

    }

    @Override
    public void doThing() {
        System.out.println("会骑电动车");
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吴琼老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值