如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类。
例如:身体和心脏的关系。又如:汽车和发动机的关系。
成员内部类的定义格式:
修饰符 class 外部类名称 {
修饰符 class 内部类名称 {
// ...
}
// ...
}
注意:内用外,随意访问;外用内,需要内部类对象。
==========================
在外部类中定义内部类
public class Body {//外部类 public class Heart{//成员内部类 //内部类的方法 public void beat(){ System.out.println("我是内部类的方法"); //成员内部类中可以直接调用外部类中的成员变量 System.out.println("我的名字是"+name); System.out.println("我的名字是"+getName()); } } private String name;//成员方法(外部类) public Body() {//空参 } public Body(String name) {//实参 this.name = name; } //外部类的方法 public void method(){ System.out.println("外部类方法"); //可以在外部类中创建内部类对象并调用内部类方法 // Heart heart = new Heart(); // heart.beat(); //或者直接匿名对象调用 new Heart().beat(); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
测试
public class Demo01InnerClass { public static void main(String[] args) { //使用成员内部类: //1、间接方式:通过外部类方法使用内部类 Body body = new Body(); body.method(); System.out.println("============="); //2、直接方式:公式:【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】 Body.Heart bh = new Body().new Heart(); bh.beat(); } }
创建类
//内部类方法中访问外部类成员变量:外部类名称.this.外部类成员变量 public class Outer { int age = 10;//外部类成员变量 public class inter{ int age = 20;//内部类成员变量 public void methodAge(){//内部类成员方法 int age = 30;//内部类局部变量 System.out.println(age);//访问局部变量 System.out.println(this.age);//访问内部类成员变量 System.out.println(Outer.this.age);//访问外部类成员变量 } } }
测试类
public class Demo02InterClass { public static void main(String[] args) { //使用内部类 Outer.inter oi = new Outer().new inter(); oi.methodAge(); } }
如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。 “局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能用了。 定义格式: 修饰符 class 外部类名称 { 修饰符 返回值类型 外部类方法名称(参数列表) { class 局部内部类名称 { // ... } } } 小节一下类的权限修饰符: public > protected > (default) > private 定义一个类的时候,权限修饰符规则: 1. 外部类:public / (default) 2. 成员内部类:public / protected / (default) / private 3. 局部内部类:什么都不能写
创建局部内部类:
public class Outer { public void methodOuter(){ //局部内部类在方法中定义 System.out.println("外部类方法"); class Inter{ int age = 20; public void methodInter(){ System.out.println("局部内部类方法"+age); } } //局部内部类在方法中创建对象,并调用方法 Inter inter = new Inter(); inter.methodInter(); } }
测试类
public class DemoMain { public static void main(String[] args) { Outer outer = new Outer(); outer.methodOuter(); } }
创建类
public class MyOuter { int age = 20;//final不写也行,但是外部成员变量值不能便,方便内部类使用 // final int age = 20; public void methodMyOuter(){ class MyInter{ public void methodMyInter(){ System.out.println(age);//在局部内部类中可以访问外部类的成员方法 } } MyInter myinter = new MyInter(); myinter.methodMyInter(); } }
测试类
public class Test { public static void main(String[] args) { MyOuter o = new MyOuter(); o.methodMyOuter(); } }
如果接口的实现类(或者是父类的子类)只需要使用唯一的一次, 那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。 匿名内部类的定义格式: 接口名称 对象名 = new 接口名称() { // 覆盖重写所有抽象方法 }; 对格式“new 接口名称() {...}”进行解析: 1. new代表创建对象的动作 2. 接口名称就是匿名内部类需要实现哪个接口 3. {...}这才是匿名内部类的内容 另外还要注意几点问题: 1. 匿名内部类,在【创建对象】的时候,只能使用唯一一次。 如果希望多次创建对象,而且类的内容一样的话,那么就需要使用单独定义的实现类了。 2. 匿名对象,在【调用方法】的时候,只能调用唯一一次。 如果希望同一个对象,调用多次方法,那么必须给对象起个名字。 3. 匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】 强调:匿名内部类和匿名对象不是一回事!!!
接口
public interface MyInterface { public void Method1(); void Method2(); }
接口实现类
public class MyInterImpl implements MyInterface{ @Override public void Method1() { System.out.println("覆盖重写1"); } @Override public void Method2() { System.out.println("覆盖重写2"); } }
测试类
public class DemoMain { public static void main(String[] args) { //匿名内部类 MyInterface obj = new MyInterface() { @Override public void Method1() { System.out.println("覆盖重写Method1方法"); } @Override public void Method2() { System.out.println("覆盖重写Method2方法"); } }; obj.Method1(); obj.Method2(); System.out.println("==============="); //匿名内部类匿名对象 new MyInterface(){ @Override public void Method1() { System.out.println("覆盖重写1"); } @Override public void Method2() { System.out.println("覆盖重写2"); } }.Method1(); new MyInterface(){ @Override public void Method1() { System.out.println("覆盖重写1"); } @Override public void Method2() { System.out.println("覆盖重写2"); } }.Method2(); } }
案例:创建一个英雄类,成员方法有姓名,年龄,武器。其中,武器单独是一个类。
英雄类
public class Hero { private String name; private int age; private Weapon weapon; public Hero() { } public Hero(String name, int age, Weapon weapon) { this.name = name; this.age = age; this.weapon = weapon; } public void Show(){ System.out.println("我是:"+getName()+",今年"+getName()+"岁。"+"我使用:"+weapon.getCode()); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Weapon getWeapon() { return weapon; } public void setWeapon(Weapon weapon) { this.weapon = weapon; } }
武器类
public class Weapon {//武器类 private String code; public Weapon() { } public Weapon(String code) { this.code = code; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } }
测试类
public class DemoMain { public static void main(String[] args) { //创建一个英雄对象 Hero hero = new Hero(); hero.setName("孙悟空"); hero.setAge(550); //创建一个武器对象 Weapon weapon = new Weapon(); weapon.setCode("金箍棒"); hero.setWeapon(weapon); hero.Show(); } }
接口作为成员变量类型
案例:创建一个英雄类,成员方法有:姓名,技能。其中,技能使用接口实现。
英雄类
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 showGame(){ System.out.println("姓名"+getName()+"触发技能:"); // skill.method(); skill.method(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Skill getSkill() { return skill; } public void setSkill(Skill skill) { this.skill = skill; } }
接口
public interface Skill { public void method(); }
接口实现类
public class SkillImpl implements Skill{ @Override public void method() { System.out.println("实现接口抽象方法覆盖重载"); System.out.println("触发技能:啪啪啪"); } }
测试类
public class DemoGame { public static void main(String[] args) { // //创建实现类对象 // SkillImpl skillImpl = new SkillImpl(); // //创建对象 // Hero hero = new Hero(); // hero.setSkill(skillImpl); // hero.setName("哪吒"); // hero.showGame(); //方法二 // //创建接口匿名内部类,写入技能方法 // Skill skill = new Skill() { // @Override // public void method() { // System.out.println("触发技能:当当当"); // } // }; // //创建对象 // Hero hero = new Hero(); // hero.setName("哪吒"); // hero.setSkill(skill); // hero.showGame(); //方法三:匿名内部类匿名对象 Hero hero = new Hero(); hero.setName("哪吒"); hero.setSkill(new Skill() { @Override public void method() { System.out.println("触发技能:咚咚咚咚"); } }); hero.showGame(); }; }
import java.util.ArrayList; import java.util.List; /* java.util.List正是ArrayList所实现的接口。 */ public interface DemoInterface { public static void main(String[] args) { //左边是接口名称,右边是实现类名称,这就是多态的写法 List<String> list = new ArrayList<>(); List<String> li = adds(list); for (int i = 0; i < li.size(); i++) { System.out.println(li.get(i)); } } public static List<String> adds(List<String> list){ list.add("张三"); list.add("李四"); list.add("王二"); list.add("麻子"); return list; } }
本章节已结束,喜欢的小伙伴可以在评论区一起交流,谢谢支持!