内部类的重名变量访问:
/* 如果出现了重名现象,那么格式为:外部类名称.this.外部类成员变量名 */ public class Outer{ int num = 10; //外部类的成员变量 public class Inner{ int num = 20 ; // 内部类的成员变量 public void method(){ int num = 30; //内部类成员方法的局部变量 System.out.printlln(num); // 局部变量,就近原则 30 System.out.printlln(this.num); //内部类的成员变量 20 System.out.printlln(Outer.this.num); //外部类的成员变量 10 } } } public class Demo02InnerClass{ public static void main(String[] args){ //外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称(); Outer.Inner obj = new Outer().new Inner(); obj.methodInner(); } }局部内部类定义:
/* 如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。 “局部”:只有当前所属的方法才能使用它,出了这个方法就不能使用了 定义: 修饰符 class 外部类名称{ 修饰符 返回值类型 外部类方法名称(){ class 局部内部类名称{ //... } } } */ public class Outer{ public void methodOuter(){ class Inner{//局部内部类 int num = 10; public void methodInner(){ System.out.println(num); //10 } } Inner inner = new Inner(); inner.methodInner(); } } public class DemoMain{ public static void main(String[] args){ Outer obj = new Outer(); obj.methodOuter(); } }类的权限修饰符: public > protected > (default) >private 定义一个类的时候,权限修饰符规则: 1.外部类:public (default) 2.成员内部类: public protected (default ) private 3.局部内部类:什么都不能写
局部内部类的final问题:
/*局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】 备注:从Java8 开始,只要局部变量事实不变,那么final关键字可以省略 原因: 1.new出来的对象在堆内存中 2.局部变量只跟着方法走,在栈内存中 3.方法运行结束之后,立刻出栈,局部变量会立刻消失。 4.new出来的对象会在堆当中持续存在,直到垃圾回收消失。 */ public class MyOuter{ public void methodOuter(){ int num = 10; //所在方法的局部变量 class MyInner{ public void methodInner(){ System.out.println(num); } } } }匿名内部类:
/* 如果接口的实现类(或者是父类的子类)只需要使用唯一的一次。 那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。 匿名内部类的定义格式: 接口名称 对象名 = new 接口名称(){ //覆盖重写所有抽象方法 }; 对格式“new 接口名称(){...}”进行解析: 1.new代表创建对象的动作 2.接口名称就是匿名内部类需要实现哪个接口 3.{...}这才是匿名内部类的内容 另外还要注意: 1.匿名对象类,在【创建对象】的时候,只能使用唯一一次。 如果希望多次创建对象,而且类的内容一样的话,那么就必须使用单独定义的实现类了。 2.匿名对象在【调用方法】的时候,只能调用唯一一次 如果希望同一个对象,调用多次方法,那么必须给对象起个名字 3.匿名内部类是省略了【实现类/子类】,但是匿名对象是省略了【对象名称】 强调:匿名内部类和匿名对象不是一回事!!! */ public interface MyInterface{ puclic abstract void method1(); //抽象方法 public abstract void method2(); } public class MyInterfaceImpl implements MyInterface{ @override public void method1(){ System.out.println("实现类覆盖重写了方法!111"); } @override public void method2(){ System.out.println("实现类覆盖重写了方法!222"); } } public class DemoMain{ public static void main(String[] args){ //MyInterfaceImpl impl = new MyInterfaceImpl(); //impl.method(); //多态 //MyInterface obj = new MyInterfaceImpl(); //obj.method(); //使用匿名内部类,但不是匿名对象,对象名称就叫objA MyInterface objA = new MyInterface(){ @override public void method1(){ System.out.println("匿名内部类实现了方法111-A"); } @override public void method2 (){ System.out.println("匿名内部类实现了方法222-A"); } }; objA.method1(); objB.method2(); System.out.println("==========="); //使用了匿名内部类,而且省略了对象名称,也是匿名对象 new MyInterface(){ @override public void method1(){ System.out.println("匿名内部类实现了方法111-B"); } @override public void method2(){ System.out.println("匿名内部类实现了方法222-B"); } }.method1(); //因为匿名对象无法调用第二次方法,所以需要再创建一个匿名内部类的匿名对象 new MyInterface(){ @override public void method1(){ System.out.println("匿名内部类实现了方法111-B"); } @override public void method2(){ System.out.println("匿名内部类实现了方法222-B"); } }.method2(); } }类作为成员变量类型:
//游戏当中的游戏类 public class Hero{ private String name; //英雄名字 private Weapon weapon; //英雄武器 private int age; //英雄的年龄 public Hero(){ } public Hero(String name, Weapon weapon, int age){ this.name = name; this.weapon = weapon; this.age = age; } public void attack(){ System.out.println("年龄为:"+age+"的"+name+"正在用"+weapon.getCode()+"攻击敌方。"); } public String getName(){ return name; } public String setName(String name){ this.name = name; } public String getWeapon(){ return weapon; } public String setWeapon(String weapon){ this.weapon = weapon; } public int getAge(){ return age; } public int setAge(int age){ this.age= age; } } public class Weapon{ private String code; //武器代号 public Weapon(){ } public Weapon(String code){ this.code = code; } public String gedCode(){ return code; } public String setCode(String code){ this.code = code; } } public class DemoMain{ public static void main(String[] args){ //创建一个英雄角色 Hero hero = new Hero(); //为英雄起一个名字,并且设置年龄 hero.setName("盖伦"); hero.setAge(20); //创建一个武器对象 Weapon weapon = new Weapon("多兰剑"); //为英雄配备武器 hero.setWeapon(weapon); //年龄为20的盖伦用多兰剑攻击了敌方 hero.attack(); } }接口作为成员变量类型:
public class Hero{ private String name; // 英雄名称 private Skill skill; //英雄技能 public Hero(){ } public Hero(String name, Skill skill){ this.name = name; this.skill = skill; } public void attack(){ System.out.println("我叫"+name+",开始释放技能:"); skill.use();//调用接口中抽象方法 System.out.println("释放技能完成"); } public String getName(){ return name; } public String setName(String name){ this.name = name; } public Skill getSkill(){ return skill; } public Skill setSkill (Skill skill){ this.skill= skill; } } public interface Skill{ void use(); //释放技能的抽象方法 } public class SkillImpl implements Skill{ @override public void use(){ System.out.println("biu~biu~biu~"); } } public class DemoGame{ public static void main(String[] args){ Hero hero = new Hero(); hero.seName("艾希"); //设置英雄名称 //设置英雄技能 //hero.setSkill(new SkillImpl); 使用单独定义的实现类 //还可以改成使用匿名内部类 /*Skill skill = new Skill(){ @override public void use(){ System.out.pirntln("pia~pia~pia"); } }; hero.setSkill(skill );*/ //进一步简化,同时使用匿名内部类和匿名对象 hero.setSkill(new Skill(){ @override public void use(){ System.out.println("biu~pia~biu~pia"); } }); hero.attack(); } }接口作为方法的参数、返回值:
/* java.util.list是ArrayList所实现的接口。 */ import java.util.ArrayList; import java.util.List; public class DemoInterface{ 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.println(result.get(i)); } } public static List<String> addNames(List<String> list){ list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("ddd"); return list; } }