• 内部类与匿名内部类



    内部类:

    * 什么是内部类: 就是在一个类的里面,在定义一个类
    * 一般用来描述事物之间的所属关系, 比如: 汽车事物里面需要描述发动机,可以使用内部类.
    * 比如: 怀宝宝的动物
    *
    * 成员变量: 定义在类的里面,方法的外面
    * 局部变量: 定义在方法的里面
    *
    * 内部类的分类:
    * 成员内部类: 定义在内的里面,方法的外面
    * 局部内部类(匿名内部类): 方法的里面
    *
    * 成员内部类的定义:
    * public class 外部类{
    * // 成员变量
    *
    * // 内部类
    * public class 内部类{
    * // 内部类的成员变量和成员方法
    * }
    * }
    *
    * 举个例子:
    * 描述一个身体里面有一个心脏类;
    *

    * 内部类的特点:
    * 1. 在内部类中(里面)可以访问,外部类的任意内容
    * 2. 如何创建一个内部类对象呢? 
    * 格式: 外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
    * 3. 在外部类中,不能访问内部类的任何内容.
    
    public class Demo01InnerClass {
    
    public static void main(String[] args) {
    //Heart h = new Heart();
    
    //创建一个内部类对象: 外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
    Body.Heart bh = new Body().new Heart();
    bh.show();
    //System.out.println(bh.life);
    
    
    }
    }
    
    package package10InnerClass;
    
    public class Body {
    
    // 成员变量
    private boolean life = true;
    
    // 成员内部内部类
    public class Heart{
    // 内部类的成员变量
    int blood = 60;
    
    // 内部类的成员方法
    public void show(){
    System.out.println("生命状态:"+life + ", 血量:"+blood);
    }
    }
    
    public void method(){
    //System.out.println(blood);
    // 如果想要访问内部类的内容,需要创建对象
    System.out.println(new Body().new Heart().blood);
    System.out.println(/*new Body().*/new Heart().blood);
    }
    }
    

      

    * 如何在内部类中,出现了和外部类同名的成员变量该如何去访问?
    * 格式: 外部类名.this.成员变量

    public class Demo01InnerClassNotice {
    
    public static void main(String[] args) {
    
    new Outer().new Inner().method();
    
    }
    }
    
    package package11InnerClass;
    
    public class Outer {
    
    private int num = 10;
    
    /*
    * Inner类和Outer类并不是继承关系
    */
    public class Inner{
    private int num = 20;
    
    public void method(){
    int num = 30;
    
    System.out.println("局部变量 = " + num);// 30
    System.out.println("本类变量 = " + this.num);//20 使用this区分
    /*
    * 在内部类中访问外部类的格式: 外部类名.this.成员变量
    */
    System.out.println("外部变量 =" + Outer.this.num);// 10
    }
    }
    }
    

      

    匿名内部类:


    * 内部类分成两种:
    * 成员内部类:
    * 局部内部类: 定义在方法里面
    *
    * 匿名内部类的格式:
    * 接口/抽象类 变量名 = new 接口/抽象类(){
    * // 重写抽象方法
    * };
    *
    * 格式解释:
    * 1. 等号的右边大括号{}, 表示定义了一个匿名的内部类.
    * 2. 等号右边的new 接口(), 表示创建了匿名内部类的一个对象
    * 3. 等号左边,使用接口去接收了,匿名内部类的对象;// 多态
    *
    * 作用:
    * 没有学习匿名内部类之前,如果要想使用接口或者抽象类,必须创建实现类,或者子类,才能使用
    * 有了匿名内部类之后,可以简化了.

    public class Demo01NoNameInnerClass {
    
    public static void main(String[] args) {
    
    //method(new Cat());
    
    // 创建匿名内部类对象, 使用对象名接收
    Animal ani = new Animal(){
    
    // 重写抽象方法
    public void eat(){
    System.out.println("小狗吃骨头");
    }
    };
    
    method(ani);
    
    // 创建匿名内部类的匿名对象,调用方法
    new Animal(){
    public void eat(){
    System.out.println("小猪吃白菜");
    }
    }.eat();
    
    System.out.println("==================");
    }
    
    public static void method(Animal ani){
    ani.eat();
    }
    }
    
    package package12NoNameInnerClass;
    //动物接口
    public interface Animal {
    
    public abstract void eat();
    }
    
    package package12NoNameInnerClass;
    //猫类实现动物接口
    public class Cat implements Animal{
    
    public void eat(){
    System.out.println("猫吃鱼");
    }
    }
    

      


    例题:

    package cn.itcast.fudao03;
    /*
    * 某市举办一场运动会,只要是会跑的都可以参加.
    要求: 使用到接口,接口作为参数,匿名内部类.
    提示: 把跑功能抽取到接口中 ,在测试类中提供参加运动会的静态方法 
    */
    public class Test01 {
    
    public static void main(String[] args) {
    new Sport() {
    
    @Override
    public void run() {
    System.out.println("参加运动会,奔跑吧小鸡儿飞");
    }
    }.run();;
    }
    
    public static void enterSport(Sport s){
    s.run();
    }
    
    }
    
    
    package cn.itcast.fudao03;
    
    public interface Sport {
    public abstract void run();
    }
    

      


    * 类作为方法的参数和返回值:
    * 不管是JDK提供的类,还是自定义的类,都可以作为方法的参数和返回值
    * 抽象可不可以作为方法的参数和返回值呢? 可以
    * 接口能不能作为方法的参数和返回值? 可以

    如:

    package package13ClassAsParaReturn;
    //抽象动物类
    public abstract class Animal {
    
    public abstract void eat();
    }
    
    package package13ClassAsParaReturn;
    //人类
    public class Person {
    
    String name;
    int age;
    
    public void eat(){
    System.out.println("吃饭了....");
    }
    }
    
    package package13ClassAsParaReturn;
    //吸烟接口
    public interface SmokerInter {
    
    public abstract void smoke();
    
    public abstract void tangtou();
    }
    
    
    package package13ClassAsParaReturn;
    /*
    * 类作为方法的参数和返回值:
    * 不管是JDK提供的类,还是自定义的类,都可以作为方法的参数和返回值
    */
    public class Demo01ClassASParaReturn {
    
    public static void main(String[] args) {
    
    
    // Object obj = null;
    // ((String)obj).length();
    
    // String作为方法的参数
    String str = new String("hello");
    methodString(str);
    
    // String作为方法的返回值
    System.out.println(methodString2());
    char[] array = methodString2().toCharArray();// 链式编程, 条件: 需要方法有返回值
    
    // person类作为方法的参数
    methodPerson(new Person());
    
    // Person类作为方法的返回值
    if(methodPerson() instanceof Person){
    Person p = (Person)methodPerson();
    p.eat();
    }
    }
    

      

    /*
    * JDK提供的类,作为方法的参数和返回值
    */

    public static void methodString(Object obj){// 多态的格式
    
    if(obj instanceof String){
    String str = (String)obj;
    System.out.println(str.length());
    }
    }
    
    public static String methodString2(){
    return new String("helloworld");
    }
    
    /*
    * 自定义的Person类作为方法的参数和返回值
    */
    public static void methodPerson(Person p ){
    System.out.println(p.name);
    System.out.println(p.age);
    System.out.println(p);// 地址值: 包名 + @ + 地址值
    }
    
    public static Object methodPerson(){
    return new Person();
    }
    }
    

     

    /*
    * 抽象可不可以作为方法的参数和返回值呢? 可以
    */ 
    package package13ClassAsParaReturn;
    /*
    * 抽象可不可以作为方法的参数和返回值呢? 可以
    */
    public class Demo02AbstractClass {
    
    public static void main(String[] args) {
    
    // 调用方法,传递有名字的对象
    Animal ani = new Animal(){
    // 重写抽象方法
    public void eat(){
    System.out.println("1: 小猫吃鱼");
    }
    };
    
    method1(ani);
    
    // 调用方法,传递匿名内部类的匿名对象
    method1(new Animal(){
    //重写抽象方法
    public void eat(){
    System.out.println("2: 小狗吃骨头");
    }
    });
    
    System.out.println("=============");
    
    // 抽象类作为方法返回值
    Animal ani2 = method3();
    ani2.eat();
    
    method3().eat();
    }
    

    /*

    * 抽象类作为方法的参数

    */
    /*
    * 抽象类作为方法的参数
    */
    public static void method1(Animal ani){
    ani.eat();
    }
    

      

    /*
    * 抽象类作为方法的返回值
    */


    /*
    * 抽象类作为方法的返回值
    */
    public static Animal method3(){
    /*
    Animal ani = new Animal(){
    // 方法重写
    public void eat(){
    System.out.println("3.小猪吃白菜");
    }
    };
    
    return ani;
    */
    
    // 返回匿名内部类的匿名对象
    return new Animal(){
    // 方法重写
    public void eat(){
    System.out.println("3.小猪吃白菜");
    }
    };
    }
    }
    

      

    /*
    * 接口能不能作为方法的参数和返回值? 可以
    */
    package package13ClassAsParaReturn;
    /*
    * 接口能不能作为方法的参数和返回值? 可以
    */
    public class Demo03InterfaceAsParaReturn {
    
    public static void main(String[] args) {
    
    // 1. 接口作为方法的参数传递
    SmokerInter si = new SmokerInter(){
    // 重写抽象方法
    public void smoke(){
    System.out.println("抽游泳烟");
    }
    
    public void tangtou(){
    System.out.println("烫头称为红色");
    }
    };
    
    method1(si);
    
    method1(new SmokerInter(){
    // 重写抽象方法
    public void smoke(){
    System.out.println("2抽游泳烟");
    }
    
    public void tangtou(){
    System.out.println("2烫头称为红色");
    }
    });
    
    
    System.out.println("=============");
    
    // 接口作为方法的返回值传递
    SmokerInter si2 = method2();
    si2.smoke();
    si2.tangtou();
    }
    /*
    * 接口作为方法的参数传递
    */
    /*
    * 接口作为方法的参数传递
    */
    public static void method1(SmokerInter si){
    si.smoke();
    si.tangtou();
    }
    /*
    * 接口作为方法的返回值
    */
    /*
    * 接口作为方法的返回值
    */
    public static SmokerInter method2(){
    return new SmokerInter(){
    public void smoke(){
    System.out.println("smoke === smoke");
    }
    
    public void tangtou(){
    System.out.println("tangtou === tangtou");
    }
    };
    }
    }
    

      


    人生就像一场路途,尝遍酸甜苦辣,方知人生苦甜.
  • 相关阅读:
    01_Linux基础篇
    Docker
    Day02_IP地址详解&进制转换&DOS基本命令与批处理
    Day01_虚拟化架构与系统部署
    重学TCP/IP协议和三次握手四次挥手
    作为一个程序员,CPU的这些硬核知识你必须会!
    通过docker-compose制作dubbo-admin和zookeeper组合服务
    双主master-master复制Err 1677故障分析
    唐宇迪-人工智能学习路线(上篇)
    DNS访问原理只需9个步骤
  • 原文地址:https://www.cnblogs.com/zennon/p/8127971.html
Copyright © 2020-2023  润新知