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
}
}
}
实战 //发红包 等下写
本文详细介绍了Java中的内部类,包括成员内部类、局部内部类和匿名内部类的定义、使用方法以及访问权限。此外,还探讨了内部类与外部类同名成员变量的访问规则,并讲解了final在局部内部类中的应用。最后,展示了类和接口作为成员变量类型以及接口作为方法参数的示例。

515

被折叠的 条评论
为什么被折叠?



