内部类 以及接口和类作为方法和参数的类型的使用方法

本文详细介绍了Java中的内部类,包括成员内部类、局部内部类和匿名内部类的定义、使用方法以及访问权限。此外,还探讨了内部类与外部类同名成员变量的访问规则,并讲解了final在局部内部类中的应用。最后,展示了类和接口作为成员变量类型以及接口作为方法参数的示例。

1.内部类的概念

一个类的内部包含着另一个类

分类:1.成员内部类
2.局部内部类(包含匿名内部类)

成员内部类的定义格式: 修饰符 class 外部类名称
{
修饰符 class 内部类名称
{

}
}
注意:内用外随意访问,外用内,需要内部类对象。

2.成员内部类的使用

1.间接方式:在外部类的方法中,使用内部类,然后main只调用外部类的方法。
2.直接方式: 创建内部类对象 公式 外部类名称.内部类名称 对象名=new 外部类名称().new 内部类名称

    //注意 内部类名字:外部类$内部类
public class Body {
        //外部类方法
    public void methodbody()
    {
        System.out.println("外部类方法");
        Heart heart=new Heart();
        heart.beat();
    }

    public  class Heart
    {
//
        //内部类成员变量
        private   String head="铁头";
        //内部类变量创建getter和setter方法和beat方法
        public  void  beat()
        {
            System.out.println("心脏跳动");
        }

        public String getHead() {
            return head;
        }

        public void setHead(String head) {
            this.head = head;
        }

        public Heart(String head) {
            this.head = head;
        }

        public Heart() {
        }

//测试
public class test1 {
    public static void main(String[] args) {
        //间接访问 现在从外部类访问内部类 方式1
        Body body = new Body();
        body.methodbody();
        System.out.println("===================");
        //直接访问 现在从外部类访问内部类 方式2
        Body.Heart one = new Body().new Heart();
        one.beat();

        /*外部类方法
         心脏跳动
         ===================
         心脏跳动*/
    }
}

    }

3.内部类和外部类同名成员变量访问

public class outer {
    int num=10;//外部类成员变量
    public class inner
    {
      
        int num=20;  //内部类成员变量

        public void method()
        {
              int num=30;
            System.out.println(num);//局部变量,就近原则
            System.out.println(this.num);//内部类成员变量
            System.out.println(outer.this.num); //外部类成员变量num
        }
    }
}
//测试
public class test1 {
    public static void main(String[] args) {
        outer.inner sc=new outer().new inner();
        sc.method();
        /*30
        * 20
        * 10*/
    }
}

4.1 局部内部类定义

定义在一个方法里面的类,并且只有这个方法可以使用他
格式;修饰符 class 类名称
{
修饰符 返回值类型 方法名(参数列表)
{
class 局部类名称
{
}
}
}

4.2 权限修饰符在不同类当中的使用
外部类:public / (default)
成员内部类: public / private / (default)/private
局部内部类:什么都不写 注意:这个什么都不写和(default)不一样,(default)是本包内可以访问,而这个什么都不写是局部的,只有当前方法可以访问。

5.内部类的final问题

局部内部类:如果希望访问所在方法的局部变量,name这个局部变量必须是有效final的

备注:从java8+开始,只要局部变量事实不变,那么final关键字可以省略(就是只赋值一次)

原因: 1.new 出来的对象在堆内存中
2.局部变量是跟着方法走的,在栈内存当中
3.方法运行结束之后,会立即出栈,局部变量就会立刻消失
4.但是 new 出来的对象还在堆当中,直到垃圾回收消失。

public class Myouter {
    public  void method()
    {   final int num=10;   
    
        class inner
        {
            public  void method()
            {
                System.out.println(num);
            }
        }
    }
}

6.匿名内部类 重点
6.1 如果接口的实现类,或者是父类的子类,只需要使用一次
这种情况下就可以省略该类的定义,则改为匿名内部类
*

  • 匿名内部类的定义格式
  • 接口名称 对象名 =new 接口名称()
  • {
    //覆盖重写所有抽象方法

};

6.2**:注意事项**

对格式 进行解析: new 接口名称{ …};
1.new 代表创建对象的动作;
2.接口名称是匿名内部类需要实现在那个接口
3.{ 。。。} 这个才是匿名内部类的内容。

另外还要注意几点问题:
1.匿名内部类,在 【创建对象】的时候,只能使用唯一的一次,如果希望多次创建对象,并且类的内容一样的话,必须单独的使用实现类。

2.匿名对象,在调用方法的时候 只能调用唯一的一次 如果希望同一个对象调用多个方法 就要命名

3.匿名内部类是省略了【实现类/子类名称】:但是匿名对象是省略了【对象名称】 强调匿名内部类和匿名对象不是一回事

下面是代码是实现 匿名内部类的两种使用方式

//创建一个接口
public interface Myinterface {
    void method1();
    void method2();
}
public class DemoMain {
    public static void main(String[] args) {


//匿名内部类  两种使用
        //第一种  使用了匿名内部类,但不是匿名对象,对象就叫做impl
           Myinterface imp =new  Myinterface (){
               @Override
               public void method1() {
                   System.out.println("匿名内部类实现了方法A");
               }

               @Override
               public void method2() {
                   System.out.println("匿名内部类实现了方法B");
               }
           };
           imp.method1();  //匿名内部类实现了方法A
           imp.method2();  //匿名内部类实现了方法B

           //第二种   使用了匿名内部类 并且省略了对象名称  它既是匿名内部类,也是匿名对象 直接在大括号后面,
       new Myinterface() {
            @Override
            public void method1() {
                System.out.println("匿名内部类实现了方法a");
            }

            @Override
            public void method2() {
                System.out.println("匿名内部类实现了方法b");
            }
            //直接dian.方法就可以了
        }.method2();        //匿名内部类实现了方法b

//因为匿名对象无法调用第二次方法,所以再需要创建一个匿名内部类 这还不如直接用第一种

    }
}

7.类作为成员变量类型

创建一个英雄类,里面有 成员变量 等级 代号 武器 和攻击方法
创建一个Weapon类 里面有武器的代号

//类作为成员变量的类型
//英雄类
public class Hero {

    private  String code;
    //类作为成员变量的类型
    private  Weapon  weapon;
    private  int level;

    public Weapon getWeapon() {
        return weapon;
    }

    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }



    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }



    public Hero(String code, Weapon weapon, int level) {
        this.code = code;
        this.weapon = weapon;
        this.level = level;
    }

    public Hero() {
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code= code;
    }
//攻击方法
    public void attack()
    {
        System.out.println("等级为"+level+"的"+code+"用"+weapon.getCode()+"攻击了你");
    }

}

//武器类
public class Weapon {
    //武器的代号
    private  String code;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public Weapon() {
    }

    public Weapon(String code) {
        this.code = code;
    }

}
//测试类
public class DemoMain {
    public static void main(String[] args) {
        //英雄名字
        Hero hero =new Hero();
        hero.setCode("盖伦");
        hero.getCode();
        //等级
        hero.setLevel(6);
        hero.getLevel();
        //武器
        //把Weapon类的地址 传给 Hero类里面的weapon对象,然后到我们要调用Hero类的attack方法
        //attack方法里的weapon可以调用Weapon类的方法
        Weapon weapon =new Weapon("大宝剑");
        hero.setWeapon(weapon);

         //攻击
        hero.attack();
    }
}

8.接口作为成员变量类型
创建一个Skill接口 包含一个使用技能use的抽象方法。一个Hero类 有英雄name和skill,还有 一个attack的方法。

//英雄类
public class Hero {
    private  Skill skill;
    private  String name;

    public Skill getSkill() {
        return skill;
    }

    public void setSkill(Skill skill) {
        this.skill = skill;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName()
    {
        return name;
    }

    public Hero() {
    }

    public Hero(Skill skill, String name) {
        this.skill = skill;
        this.name = name;
    }
    //攻击方法
public void attack()
{
    System.out.println("我叫"+name+"开始释放技能");
    skill.Use();
    System.out.println("技能释放完成");
}

}

//接口
public interface Skill {
    void Use();


}
//测试
public class Demogame {
    public static void main(String[] args) {
        Hero hero =new Hero();
        hero.setName("艾希");
     //方法1 使用匿名实现类
             Skill skill =new Skill() {
            @Override
            public void Use() {
                System.out.println("biubiubiu");

            }
        };
        //让Hero当中的Skill skill得到Skill接口的地址
           //hero就可以调用Skill接口当中已经覆盖重写的实现类的内容
         hero.setSkill(skill);
        hero.attack();
      /*我叫艾希开始释放技能
        biubiubiu
        技能释放完成*/


      //方法2 注意,这个还可以同时使用匿名对象和匿名内部类

  hero.setSkill( new Skill() {
            @Override
            public void Use() {
                System.out.println("papapapa");
            }
       });
        hero.attack();
/*
*     我叫艾希开始释放技能
      papapapa
      技能释放完成*/
   
    }
}

9.接口作为方法的参数或类型

List是ArrayList所实现的接口

创建一个集合,并且往里面导入几组数字

import java.util.ArrayList;
import java.util.List;
/*import java.util.List;正是ArrayList所实现的接口,就可以用多态写法*/
public class Demointerface {
    //左边是接口 右边是实现类名称
 List<String> list= new ArrayList<String>();
 //用接口作为方法的参数和类型
 public  static  List<String> addNames(List<String> list)
 {
  list.add("a");
  list.add("b");
  list.add("c");
  //用接口作为方法的返回值
  return list;
 }

    public static void main(String[] args) {
   List<String> list=new ArrayList<>();
  //引用类型的赋值,赋的是地址值
       List<String> result =addNames(list);
        for (int i = 0; i < result.size(); i++)
        {
            System.out.print(result.get(i)+" ");  // a  b  c

        }
    }
}

实战 //发红包 等下写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值