内部类及引用类型

概述

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。

成员内部类

成员内部类 :定义在类中方法外的类。
定义格式:

class 外部类 {
    class 内部类{
     }
  }

在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car 中包含发动机类Engine ,这时, Engine 就可以使用内部类来描述,定义在成员位置。
代码举例:

class Car { //外部类
   class Engine { //内部类
   }
 }

访问特点

  • 内部类可以直接访问外部类的成员,包括私有成员
  • 外部类要访问内部类的成员,必须要建立内部类的对象。
如何使用成员内部类

1、间接方式:在外部类的方法当中,使用内部类,然后main只是调用外部类的方法
2、直接方式:公式:
类名称 对象名 = new 类名称();
【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称()】

  public class DemoInnerClasss{
      public static void main(String[] args){
         Body body = new Body();//外部类对象
         //通过外部类的对象,调用外部类的方法,里面间接在使用内部类heart
         body.methodBody;
          
          //按照公式写:
          Body.Heart heart =new Body().new Heart();
          heart.beat();
        }
     }
成员变量重名

如果出现重名现象,那么格式是:外部类名称.this外部成员变量名

public class Outer{
  int num =10;//外部类成员变量
     public class Inner{
        int num = 20;
          public void methodInner(){
            int num = 30;//内部类方法的局部变量
            System.out.println(num);
            System.out.println(this.num);
            System.out.println(Outer.this.num);
           }
         }
局部内部类

定义格式:

修饰符 class 外部类名称{
     修饰符 返回值类型  外部类方法名称(参数列表){
         class 局部内部类名称{
         //...
         }
        }
       }
类的权限修饰符总结

public>protected>(default)>private
定义一个类的时候i,权限修饰符规则:
1、外部类:public/(default)
2、成员内部类:public>protected>(default)>private
3、局部内部类:什么都不写

匿名内部类

如果接口的实现类(或者父类的子类)只需要使用唯一的一次,那么这种情况下就可以省略掉该类的定义,而改为使用匿名内部类
匿名内部类的使用格式:

接口名称 对象名 = new 接口名称(){
  //覆盖重写所有抽象类方法
  }

对格式“new 接口名称(){…}”进行解析:
1、new 代表创建对象的动作
2、接口名称就是匿名内部类需要实现那个接口
3、{…}这才是匿名内部类的内容
另外还需注意:
1、匿名内部类在【创建对象】的时候,只能使用唯一的一次
如果希望多次创建对象,而且类的内容一样的话,那么久必须使用单独定义的类了
2、匿名对象在【调用方法】的时候,只能调用唯一的一次
如果希望同一个对象,多次调用方法,那么必须给对象起个名字
3、匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】
强调匿名内部类和匿名对象不是一回事

package Demo07;

public class DemoInterface01 {
    public static void main(String[] args) {
        //使用匿名内部类
        MyInterface obj = new MyInterface() {
            @Override
            public void method1() {
                System.out.println("匿名类实现了方法111");
            }

            @Override
            public void method2() {
                System.out.println("匿名类实现了方法222");

            }

        };
        obj.method1();
        obj.method2();
        //使用了匿名内部类,而且省略了对象名称,也是匿名对象
        new MyInterface(){

            @Override
            public void method1() {
                System.out.println("匿名类实现了方法AAA");
            }


            @Override
            public void method2() {
                System.out.println("匿名类实现了方法BBB");
            }
        }.method1();
        // 因为匿名对象无法调用第二次方法,所以需要在创建一个匿名内部类对象
        new MyInterface() {
            @Override
            public void method1() {
                System.out.println("匿名类实现了方法AAA");

            }

            @Override
            public void method2() {
                System.out.println("匿名类实现了方法BBB");

            }
        }.method2();
    }
}

引用类型用法总结

基本类型可以作为成员变量,作为方法的参数,作为方法的返回值,引用类型也是可以的

class作为成员变量

类作为成员变量时,对他进行赋值的操作,实际上是赋给他该类一个对象

interface作为成员变量

接口是对方法的封装,对应游戏当中,可以看作是扩展游戏角色的技能。所以,如果想扩展更强大技能,我们在Role 中,可以增加接口作为成员变量,来设置不同的技能。
我们使用一个接口,作为成员变量,以便随时更换技能,这样的设计更为灵活,增强了程序的扩展性。
接口作为成员变量时,对它进行赋值的操作,实际上,是赋给它该接口的一个子类对象。

package Demo07;

public class Role {
   private int id;
   private int blood;//生命值
   private String name;
    //添加武器属性
    private Weapon wp;
    private Armour ar;
    private FaShuSkill fs;

    public Role() {
    }

    public Role(int id, int blood, String name, Weapon wp, Armour ar,FaShuSkill fs) {
        this.id = id;
        this.blood = blood;
        this.name = name;
        this.wp = wp;
        this.ar = ar;
        this.fs = fs;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getBlood() {
        return blood;
    }

    public void setBlood(int blood) {
        this.blood = blood;
    }

    public String getName() {
        return name;
    }

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

    public Weapon getWp() {
        return wp;
    }

    public void setWp(Weapon wp) {
        this.wp = wp;
    }

    public Armour getAr() {
        return ar;
    }

    public void setAr(Armour ar) {
        this.ar = ar;
    }

    public FaShuSkill getFs() { return fs; }

    public void setFs(FaShuSkill fs) { this.fs = fs; }


    //攻击方法
    public void attack(){
        System.out.println("使用"+wp.getName()+"造成"+wp.getHurt()+"点伤害");
    }
    //穿戴盔甲
    public void wear(){
        this.blood +=ar.getProtect();
        System.out.println("穿上"+ar.getName()+",生命值增加"+ar.getProtect());
    }
    public void FaShuSkillAttack(){
        System.out.print("发动法术攻击:");
        fs.faShuAttack();
        System.out.println("攻击完毕");
    }


}

package Demo07;

public class DemoClassTest {
    public static void main(String[] args) {
        //创建Weapon对象
        Weapon wp = new Weapon("屠龙刀",9999);
        //创建Weapon对象
        Armour ar = new Armour("麒麟甲",10000);
        //创建Weapon对象
        Role r = new Role();
        r.setWp(wp);//设置武器属性
        r.setAr(ar);//设置盔甲属性
        r.attack();
        r.wear();
        r.setFs(new FaShuSkill() {
            @Override
            public void faShuAttack() {
                System.out.println("逆转乾坤");
            }
        });
        r.FaShuSkillAttack();

        new FaShuSkill(){
            @Override
            public void faShuAttack() {
                System.out.println("纵横天下");
            }
        }.faShuAttack();
        r.FaShuSkillAttack();

    }
}

interface作为方法参数和返回值类型

当接口作为方法的参数时,需要传递什么呢?当接口作为方法的返回值类型时,需要返回什么呢?对,其实都是它的子类对象。 ArrayList 类我们并不陌生,查看API我们发现,实际上,它是 java.util.List 接口的实现类。所以,当我们看见List 接口作为参数或者返回值类型时,当然可以将ArrayList 的对象进行传递或返回。
接口作为参数时,传递它的子类对象。
接口作为返回值类型时,返回它的子类对象。

package Demo07;

import java.util.ArrayList;
import java.util.List;

public class DemoInterfaceTest02 {
    public static void main(String[] args) {
        ArrayList<Integer> srcList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            srcList.add(i);

        }
        List list = getEvenNum(srcList);
        System.out.println(list);

    }
    public static List<Integer> getEvenNum(List<Integer> list){
        ArrayList<Integer> evenList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Integer inter = list.get(i);
            if (inter%2==0){
                evenList.add(i);
            }

        }
        return evenList;

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值