【Java16】内部类


1.内部类

package com.itheima05.innerclass;
/*
*   1. 定义在一个类A内部的另外一个类B, 那么A称之为外部类, B称之为内部类
*        内部类: 访问受限(要通过外部来访问内部)
*   2. 成员内部类: 定义一个类成员位置的类 (少见)
*        1. 语法:外部类名.内部类名(声明) 变量名 = 外部类对象.new 内部类();
*        2. 编译:多了一个:OuterClass$InnerClass.class
*   3. 局部内部类: 定义在一个方法里的类。只能当前方法内使用,其他方法不能使用
*/
public class InnerDemo {
    
     //有.class文件
    public static void main(String[] args) {
    
    
          class MethodClass{
    
     //定义在main方法里称为局部内部类  
              int methodField;
              void method(){
    
    
              }
          }         
        MethodClass mc = new MethodClass(); //上面的类
        mc.methodField = 1;
        mc.method();
    }

    public static void method01(){
    
    
        OuterClass oc = new OuterClass(); //main方法外面即下面的类
        oc.outerField = 1;
        oc.outerMethod();
        
        OuterClass.InnerClass ic = oc.new InnerClass(); //main方法外面即下面的类
        ic.innerFiled = 2;
        ic.innerMethod();	
        
		// MethodClass mc = new MethodClass(); //错误,不能访问
    }
}

class OuterClass{
    
     //外部类 //有.class文件
    int outerField; //成员
    void outerMethod(){
    
     
    }    
    class InnerClass{
    
     //成员内部类 //有.class文件
        int innerFiled;
        void innerMethod(){
    
    
        }
    }
}

在这里插入图片描述

2.匿名内部类

在这里插入图片描述

package com.itheima05.innerclass;
/*
*     1. 匿名内部类 属于 方法/局部内部类 的一种
*     2. 匿名内部类 没有 类名
*     3. 目的 : 简化代码编写
*         new 父类/父接口() { //class body 即类体
*              如果有抽象方法,必须重写
*          }
*        创建出来的是父类/父接口的子类对象
*        原理:  定义类+创建对象  合二为一
*/
public class InnerDemo02 {
    
    
    public static void main(String[] args) {
    
    
        Dog twoHa = new Dog(); //Animal twoHa = new Dog();也可以即多态
        voice(twoHa); //汪汪叫
        
//11111111111111111111111111111111111111111111111111111111111111111111111111111	
        //InnerDemo02$Wolf.class //第一个内部类有名字Wolf   
		class Wolf implements Animal{
    
     //以前这类写在main方法外 //定义类
            @Override
            public void shout() {
    
    
                System.out.println("嗷嗷叫");
            }
        }
        Wolf greyTai = new Wolf();  //创建对象
        voice(greyTai); //嗷嗷叫
        
//111111111111111111111111111111111111111111111111111111111111111111111111111111111
        /*
        * 类名如dog,wolf其实在某些场景下一定都不重要,重要的类体(重写shout方法)
        * 语法: 多了个类体,但是把类名隐藏掉了叫匿名
        * 省略: 1. 以前:  定义类  然后 创建对象
        *       2. 现在: 创建对象+定义类  合二为一
        */
		// Animal a = new Animal(); //接口不能实例化,如下加方法体        
        // 父接口 变量 = 父接口子类对象 (向上转型)
        Animal a = new Animal(){
    
     //多了一个大括号,InnerDemo02$1.class 第二个内部类也是第一个匿名内部类用1
            @Override
            public void shout() {
    
    
                System.out.println("嘎嘎叫"); 
            }
        };
        voice(a); //嘎嘎叫
        
//111111111111111111111111111111111111111111111111111111111111111111111111111111111
       // InnerDemo02$2.class  //第三个内部类也是第二个匿名内部类用2
       Animal b = new Dog(){
    
     //这样写也可以,同上
            @Override
            public void shout() {
    
    
                System.out.println("呱呱叫");
            }
        };
        b.shout(); // 呱呱叫
        
//1111111111111111111111111111111111111111111111111111111111111111111111111111111
        //匿名内部类的匿名对象,最简洁  //InnerDemo02$3.class
       voice(new Animal() {
    
    
           @Override
           public void shout() {
    
    
               System.out.println("喵喵叫"); // 喵喵叫
           }
       });
    }	
    //Animal接口, 接口不能实例化
    private static void voice(Animal a) {
    
    
        a.shout();
    }
}

//111111111111111111111111111111111111111111111111111111111111111111111111111
interface Animal{
    
     //一般不用abstract Animal
    void shout(); //叫
}
class Dog implements Animal{
    
     //多态,匿名内部类不用
    @Override
    public void shout() {
    
    
        System.out.println("汪汪叫");
    }
}

在这里插入图片描述
如下这个类对象就用一次,没必要取个名字,如果取名字还要单独的.java文件
在这里插入图片描述

3.练习

子类特有方法不是子类重写方法,如下2解决
在这里插入图片描述

package com.atguigu.test10;
/*
(1)声明一个抽象类Father,包含抽象方法:public abstract void method();
(2)用匿名内部类继承Father,并重写抽象方法,打印“hello 孩子"。并调用子类对象的method方法
*/
public class TestExer3 {
    
    
	public static void main(String[] args) {
    
    
		/*new Father(){
			public void method(){
				System.out.println("hello 孩子");
			}
		}.method();*/
		
		// 上下一样
		Father f = new Father(){
    
    
			public void method(){
    
    
				System.out.println("hello 孩子");
			}
		};
		f.method(); //hello 孩子
	}
}
abstract class Father{
    
    
	public abstract void method();
}

接口、抽象类可以理解成是模糊不定的东西,要使用它的特质必须要实例化。实例化不能直接通过new,如下代码不同于普通的实例化对象,而是通过new一个实现接口的匿名内部类Runnable,使用{}具体实现接口。
在这里插入图片描述

package com.atguigu.test10;
import java.util.Arrays;
import java.util.Comparator;

public class TestExer4 {
    
    
	@SuppressWarnings("all")
	public static void main(String[] args) {
    
    
		//(2)在测试类中创建Employee数组
		Employee[] all = new Employee[3];
		all[0] = new Employee(2, "张三", 10000);
		all[1] = new Employee(1, "李四", 30000);
		all[2] = new Employee(3, "王五", 20000);	
			
	//(3)分别调用Arrays.sort(数组,Comparator),用匿名内部类实现按照编号升序排列,接口一定要重写方法
		Arrays.sort(all, new Comparator(){
    
    
			@Override
			public int compare(Object o1, Object o2) {
    
    
				Employee e1 = (Employee) o1;
				Employee e2 = (Employee) o2;
				return e1.getId() - e2.getId();
			}			
		});
		for (int i = 0; i < all.length; i++) {
    
    
			System.out.println(all[i]);
		}
		
//		(4)分别调用Arrays.sort(数组,Comparator),用匿名内部类实现按照薪资升序排列
		Arrays.sort(all , new Comparator() {
    
    
			@Override
			public int compare(Object o1, Object o2) {
    
    
				Employee e1 = (Employee) o1;
				Employee e2 = (Employee) o2;				
				if(e1.getSalary() > e2.getSalary()){
    
    
					return 1;
				}else if(e1.getSalary() < e2.getSalary()){
    
    
					return -1;
				}
				return 0;
			}
		});
		for (int i = 0; i < all.length; i++) {
    
    
			System.out.println(all[i]);
		}
	}
}

//(1)声明一个员工类Employee,有属性:编号、姓名、薪资
class Employee{
    
    
	private int id;
	private String name;
	private double salary;
	public Employee(int id, String name, double salary) {
    
    
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
	}
	public Employee() {
    
    
		super();
	}
	public int getId() {
    
    
		return id;
	}
	public void setId(int id) {
    
    
		this.id = id;
	}
	public String getName() {
    
    
		return name;
	}
	public void setName(String name) {
    
    
		this.name = name;
	}
	public double getSalary() {
    
    
		return salary;
	}
	public void setSalary(double salary) {
    
    
		this.salary = salary;
	}
	@Override
	public String toString() {
    
    
		return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + "]";
	}	
}

在这里插入图片描述
B站/知乎/微信公众号:码农编程录
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43435675/article/details/107420918