文章目录

  • 1、final关键字
  • 2、权限修饰符
  • 3、内部类
    • 3.1 成员内部类
    • 3.2 匿名内部类
  • 4、引用类型用法总结
    • 4.1 class作为成员变量
    • 4.2 interface作为成员变量
    • 4.3 interface作为方法参数和返回值类型
  • 5、总结

1、final关键字

  学习了继承后,我们知道,子类可以在父类的基础上改写父类内容,比如,方法重写。那么我们能不能随意的继承API中提供的类,改写其内容呢?显然这是不合适的。为了避免这种随意改写的情况,Java提供了 final 关键字,用于修饰不可改变内容。被修饰的类,不能被继承;被修饰的方法,不能被重写;被修饰的变量,不能被重新赋值。
  查询 API发现像 public final class String 、 public final class Math 、 public final class Scanner等,很多我们学习过的类,都是被final修饰的,目的就是供我们使用,而不让我们所以改变其内容。

//修饰类
final class 类名 {}//修饰方法
修饰符 final 返回值类型 方法名(参数列表){//方法体
}//修饰变量
public class FinalDemo1 {public static void main(String[] args) {// 声明变量,使用final修饰final int a;// 第一次赋值a = 10;// 第二次赋值a = 20; // 报错,不可重新赋值// 声明变量,直接赋值,使用final修饰final int b = 10;// 第二次赋值b = 20; // 报错,不可重新赋值}
}public class FinalDemo2 {public static void main(String[] args) {// 创建 User 对象final User u = new User();// 创建 另一个 User对象u = new User(); // 报错,指向了新的对象,地址值改变。// 调用setName方法u.setName("张三"); // 可以修改}
}//修饰成员变量
//显示初始化
public class User {final String USERNAME = "张三";private int age;
}//修饰成员变量
//构造方法初始化
public class User {final String USERNAME ;private int age;public User(String username, int age) {this.USERNAME = username;this.age = age;}
}

  被final修饰的常量名称,一般都有书写规范,所有字母都大写。

2、权限修饰符

  在Java中提供了四种访问权限,使用不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限,不同权限的访问能力如下:

权限范围 public protected default private
同一个类中
同一个包中(子类与无关类)
不同包的子类
不同包中的无关类

  可见,public具有最大权限。private则是最小权限。编写代码时,如果没有特殊的考虑,建议这样使用权限:成员变量使用 private ,隐藏细节;构造方法使用 public ,方便创建对象;成员方法使用 public ,方便调用方法。不加权限修饰符,其访问能力与default修饰符相同

3、内部类

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

3.1 成员内部类

  成员内部类就是定义在类中方法外的类。

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

  内部类可以直接访问外部类的成员,包括私有成员。外部类要访问内部类的成员,必须要建立内部类的对象。(看内部类时,把外部类当作全局环境)

package cn.klb.domain;/*** @Author: Konglibin* @Description:* @Date: Create in 2020/3/11 14:19* @Modified By:*/public class InnerDemo {public static void main(String[] args) {// 创建外部类对象Person p = new Person();// 创建内部类对象Person.Heart heart = p.new Heart();// 调用内部类方法heart.jump();  //心脏在跳动// 调用外部类方法p.setLive(false);// 调用内部类方法heart.jump();   //心脏不跳了}
}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;}
}

  内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的 .class文件,但是前面冠以外部类的类名和$符号 。比如,Person$Heart.class

3.2 匿名内部类

  这个名字值得吐槽,让人以为是一个类,其实匿名内部类是“带具体实现的”、“父类或者父接口的”、“匿名的”子类对象。看到没,这货是一个对象。最常用到的内部类就是匿名内部类了。以接口举例,当你使用一个接口时,似乎得做如下几步操作:

  1. 定义子类
  2. 重写接口方法
  3. 创建子类对象
  4. 调用重写后的方法

  可是我们的目的,只是用这个方法,为了更简洁的调用这个方法,就得使用匿名内部类了。

//格式
new 父类名或者接口名(){// 方法重写@Overridepublic void method() {// 执行语句}
};

  下面以接口为例,阐述匿名内部类的用法,要细品:

//定义一个抽象类
public abstract class FlyAble{public abstract void fly();
}//创建匿名内部类并调用
public class InnerDemo {public static void main(String[] args) {/*1.等号右边:是匿名内部类,定义并创建该接口的子类对象2.等号左边:是多态赋值,接口类型引用指向子类对象*/FlyAble  f = new FlyAble(){public void fly() {System.out.println("我飞了~~~");}};//调用 fly方法,执行重写后的方法f.fly();}
}

  看到没,等号右边是匿名内部类,但他真的是一个对象!(再一次吐槽这个名字)
  通常在方法的形式参数是接口或者抽象类时,也可以将匿名内部类作为参数传递。代码如下:

//定义一个抽象类
public abstract class FlyAble{public abstract void fly();
}public class InnerDemo2 {public static void main(String[] args) {/*1.等号右边:定义并创建该接口的子类对象2.等号左边:是多态,接口类型引用指向子类对象*/FlyAble  f = new FlyAble(){public void fly() {System.out.println("我飞了~~~");}};// 将f传递给showFly方法中showFly(f);}public static void showFly(FlyAble f) {f.fly();}
}

  以上两步,也可以简化为一步,代码如下:

//定义一个抽象类
public abstract class FlyAble{public abstract void fly();
}public class InnerDemo3 {public static void main(String[] args) {           /*创建匿名内部类,直接传递给showFly(FlyAble f) */showFly(new FlyAble() {public void fly() {System.out.println("我飞了~~~");}});}public static void showFly(FlyAble f) {f.fly();}
}

4、引用类型用法总结

4.1 class作为成员变量

  在定义一个类Role(游戏角色)时,代码如下:

class Role {int id; // 角色id  int blood; // 生命值  String name; // 角色名称
}

  使用 int 类型表示 角色id和生命值,使用 String 类型表示姓名。此时, String 本身就是引用类型,由于使用的方式类似常量,所以往往忽略了它是引用类型的存在。

4.2 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() {@Overridepublic void faShuAttack() {System.out.println("纵横天下");}});// 发动法术攻击role.faShuSkillAttack();// 更换技能role.setFaShuSkill(new FaShuSkill() {@Overridepublic void faShuAttack() {System.out.println("逆转乾坤");}});// 发动法术攻击role.faShuSkillAttack();}
}

  这里我们可以更进一步体会到接口的作用,比如一个函数的参数是int i,你肯定得仍进去一个int类型数字,而不是傻傻的扔一个字母i进去,这个数字就是实例。所谓用interface作为成员变量,其实和基本类型做成员变量没啥区别。

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

  跟上面小节的解释一样,所谓interface作为方法参数和返回值类型,使用起来和基本类型一模一样,只要不要傻傻的扔一个字母i进去就行,肯定是一个实例对象才能作为输入。然后interface的实例对象有最标准的写法,就是:定义子类–>重写接口方法–>创建子类对象。但是一个参数输入,就得是一个对象,而不是一串步骤,为了把这一串步骤转成一步,就使用匿名内部类(再次强调!匿名内部类是对象!不是类!)。
  当接口作为方法的参数时,需要传递什么呢?当接口作为方法的返回值类型时,需要返回什么呢?对,其实都是它的子类对象。 ArrayList 类我们并不陌生,查看API我们发现,实际上,它是 java.util.List 接口的实现类。所以,当我们看见 List 接口作为参数或者返回值类型时,当然可以将 ArrayList 的对象进行传递或返回。这里的 java.util.List 就好像是基本类型的int,ArrayList 的对象就好像int类型的数字3。
  请观察如下方法:获取某集合中所有的偶数。

public class Test {/*方法的返回值类型是List,说明返回值就是List的对象方法的参数是List,说明方法的输入必须是List类型的然而List<Integer>是一个接口,那就得使用实现了List的类代替它*/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 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);}
}

5、总结

  final修饰的类不可以被继承,final修饰的方法不能被重写。权限修饰符有四种:public、protected、default和private,其权限大小依此降低。内部类就是定义在类里面的类。引用类型作为成员变量和基本类型用起来差不多,区别在于引用类型成员变量保存的是地址值。引用类型作为方法参数和方法返回值,传递的都是地址。
  (本章内容为自学笔记,转载请注明来源,有错误地方欢迎评论区指出。)

[JavaSE-10]权限、内部类和引用类型相关推荐

  1. final、权限、内部类、引用类型

    final.权限.内部类.引用类型 1 final关键字 1.1 概述 学习了继承后,我们知道,子类可以在父类的基础上改写父类内容,比如,方法重写.那么我们能不能随意的继承API中提供的类,改写其内容呢? ...

  2. 8.final、权限、内部类、引用类型

    final.权限.内部类.引用类型 第一章 final关键字 学习了继承后,我们知道,子类可以在父类的基础上改写父类内容,比如,方法重写.那么我们能不能随意的继承 API中提供的类,改写其内容呢?显然 ...

  3. java——final关键字、权限、内部类、引用类型

    final关键字代表最终.不可改变的.常见四种用法: 1. 可以用来修饰一个类 2. 可以用来修饰一个方法 3. 还可以用来修饰一个局部变量 4. 还可以用来修饰一个成员变量 当final关键字用来修 ...

  4. java_final、权限、内部类、引用类型

    第一章 final关键字 1.1 概述 学习了继承后,我们知道,子类可以在父类的基础上改写父类内容,比如,方法重写.那么我们能不能随意的继承 API中提供的类,改写其内容呢?显然这是不合适的.为了避免 ...

  5. Java基础(9)——final、权限、内部类、引用类型

    目录 第一章 final关键字 1.概述 2.使用 final修饰的类 final修饰方法 final修饰局部变量 final修饰成员变量 第二章 权限修饰符 第三章 内部类 1.概述 2.成员内部类 ...

  6. 09,final、权限、内部类、引用类型

    第一章 final关键字 1.1 概述 子类可以在父类的基础上改写父类内容,比如,方法重写.能不能随意的继承API中提供的类,改写其内容呢?显然这是不合适的.为了避免这种随意改写的情况,Java提供了 ...

  7. JavaSE 接口与内部类

    文章目录 第十三章 面向对象高级-抽象 13.1 抽象类 13.1.1 抽象类 13.1.2 注意 13.2 接口 13.2.1 接口 13.2.2 注意 13.2.3 默认方法 13.2.4 接口与 ...

  8. 2021.5.10笔记 内部类

    内部类 内部类 内部类的概念 内部类的使用 内部类的同名变量访问 局部内部类(包含匿名内部类) 局部内部类定义 局部内部类的final问题 匿名内部类 类作为成员变量类型 接口作为成员变量类型 接口作 ...

  9. 每日学习-Java基础(十)接口和继承10(内部类)

    一.内部类 内部类 // 内部类有四种类型 // 1-非静态内部类 // 2-静态内部类 // 3-匿名类 // 4-本地类 1.非静态内部类 package ia10_innerClass;publ ...

最新文章

  1. 【网络流】解题报告:luogu P3376 【模板】网络最大流
  2. Microbiome:香港理工李向东组-医院源可吸入耐药基因与宿主群落、临床关联和环境风险...
  3. pytorch强化学习训练倒摆小车
  4. php计划任务每天12点执行一次,php定时执行计划任务之直接在php中执行
  5. 【资源汇总分享】Android开发资源汇总之一
  6. Java EE MVC:处理表单验证
  7. SylixOS下移植glib时clock_gettime函数分析
  8. 《SEO实战密码》读后一点感受
  9. Java 多线程执行
  10. LoRa全链路打通教程01 - LoRa网关配置查看和修改方法详解(以ST P-NUCLEO-LRWAN3 套件为例)
  11. excel选中行变色
  12. 阿里云和AWS对比研究三——存储产品对比
  13. 对数似然值 matlab,matlab aic准则 怎么计算对数似然值
  14. 3.2JavaScript网页编程——JavaScript网页编程基础
  15. omnet++ 4维的立方体网络仿真
  16. VehicleNet: Learning Robust Visual Representation for Vehicle Re-identification(车辆网络:学习用于车辆再识别的鲁棒视觉)
  17. jeesite 之上传图片
  18. html项目的致谢词,毕业论文的致谢词范文(精选5篇)
  19. C1认证学习六(HTTPS)
  20. docker 安装及部署

热门文章

  1. Aspose.PDF for Java 21.6 Crack
  2. Error:javaJDK isn‘t specified for module问题解决
  3. C# opencvSharp实现鼠标移动选择感兴趣区域(ROI)
  4. Gradle 完整指南(Android)
  5. Filter-Policy简述
  6. 4.1 IGRP的实现
  7. 燕十八公益教程-学习感想
  8. 微支付jsapi巨坑 微支付 jsapi java
  9. 常见的智能推荐算法(总结)
  10. hadoop实现云音乐排行榜