day10
一、final关键字
final: 不可改变。可以用于修饰类、方法和变量。
类:被修饰的类,不能被继承。
方法:被修饰的方法,不能被重写。
变量:被修饰的变量,不能被重新赋值。
局部变量——引用类型 引用类型的局部变量,被final 修饰后,只能指向一个对象,地址不能再更改。
但是不影响对象内部的成员变量值的 修改,代码如下: public class FinalDemo2 { public static void main(String[] args) { // 创建 User对象 final User u = new User(); // 创建 另一个 User对象 u = new User(); // 报错,指向了新的对象,地址值改变。 // 调用setName方法 u.setName ("张三"); // 可以修改 } }
二、内部类
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类
成员内部类 :定义在类中方法外的类。 定义格式: class 外部类 { class 内部类{ } }
访问特点 内部类可以直接访问外部类的成员,包括私有成员。 外部类要访问内部类的成员,
必须要建立内部类的对象。 创建内部类对象格式: 外部类名.内部类名 对象名 = new 外部类型().new 内部类型(); 访问演示,代码如下: 定义类: public class Person { private boolean live = true; class Heart { public void jump() { // 直接访问外部类成员 if (live) { System.out.println ("心脏在跳动"); } else { System.out.println ("心脏不跳了"); } } } public boolean isLive() { return live; } public void setLive(boolean live) { this.live = live; } } 定义测试类: public class InnerDemo { public static void main(String[] args) { // 创建外部类对象 Person p = new Person(); // 创建内部类对象 Heart heart = p.new Heart(); // 调用内部类方法 heart.jump(); // 调用外部类方法 p.setLive (false); // 调用内部类方法 heart.jump(); } } 输出结果: 心脏在跳动 心脏不跳了
内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类名 和$符号 。
比如,Person$Heart.class
三、引用类型
实际的开发中,引用类型的使用非常重要,也是非常普遍的。我们可以在理解基本类型的使用方式基础上,进一步 去掌握引用类型的使用方式。基本类型可以作为成员变量、作为方法的参数、作为方法的返回值,那么当然引用类 型也是可以的。
interface作为成员变量 接口是对方法的封装,对应游戏当中,可以看作是扩展游戏角色的技能。所以,如果想扩展更强大技能,我们在 Role 中,可以增加接口作为成员变量,来设置不同的技能。 定义接口: // 法术攻击 public interface FaShuSkill { public abstract void faShuAttack(); } 定义角色类: public class Role { FaShuSkill fs; public void setFaShuSkill(FaShuSkill fs) { this.fs = fs; } // 法术攻击 public void faShuSkillAttack(){ System.out.print("发动法术攻击:"); fs.faShuAttack(); System.out.println("攻击完毕"); } } 定义测试类: public class Test { public static void main(String[] args) { // 创建游戏角色 Role role = new Role(); // 设置角色法术技能 role.setFaShuSkill(new FaShuSkill() { @Override public void faShuAttack() { System.out.println("纵横天下"); } }); // 发动法术攻击 role.faShuSkillAttack(); // 更换技能 role.setFaShuSkill(new FaShuSkill() { @Override public void faShuAttack() { System.out.println("逆转乾坤"); } }); // 发动法术攻击 role.faShuSkillAttack(); } } 输出结果: 发动法术攻击:纵横天下 攻击完毕 发动法术攻击:逆转乾坤 攻击完毕 我们使用一个接口,作为成员变量,以便随时更换技能,这样的设计更为灵活,增强了程序的扩展性。 接口作为成员变量时,对它进行赋值的操作,实际上,是赋给它该接口的一个子类对象。
interface作为方法参数和返回值类型 当接口作为方法的参数时,需要传递什么呢?当接口作为方法的返回值类型时,需要返回什么呢?对,其实都是它的 子类对象。 ArrayList 类我们并不陌生,查看API我们发现,实际上,它是 java.util.List 接口的实现类。所 以,当我们看见 List 接口作为参数或者返回值类型时,当然可以将 ArrayList 的对象进行传递或返回。 请观察如下方法:获取某集合中所有的偶数。 定义方法: public static List<Integer> getEvenNum(List<Integer> list) { // 创建保存偶数的集合 ArrayList<Integer> evenList = new ArrayList<>(); // 遍历集合list,判断元素为偶数,就添加到evenList中 for (int i = 0; i < list.size(); i++) { Integer integer = list.get(i); if (integer % 2 == 0) { evenList.add(integer); } } /* 返回偶数集合 因为getEvenNum方法的返回值类型是List,而ArrayList是List的子类, 所以evenList可以返回 */ return evenList; } 调用方法: public class Test { public static void main(String[] args) { // 创建ArrayList集合,并添加数字 ArrayList<Integer> srcList = new ArrayList<>(); for (int i = 0; i < 10; i++) { srcList.add(i); } /* 获取偶数集合 因为getEvenNum方法的参数是List,而ArrayList是List的子类, 所以srcList可以传递 */ List list = getEvenNum(srcList); System.out.println(list); } } 接口作为参数时,传递它的子类对象。 接口作为返回值类型时,返回它的子类对象。