final关键字

final关键字代表最终、不可改变的。

常见四种用法

1、当final关键字用来修饰一个类的时候,格式:

public final class 类名称 {
// …
}

含义:当前这个类不能有任何的子类。(太监类) 不能被继承。
注意:一个类如果是final的,那么其中所有的成员方法都无法进行覆盖重写(因为没儿子。)
2、当final关键字用来修饰一个方法的时候,这个方法就是最终方法,也就是不能被覆盖重写。
格式:

修饰符 final 返回值类型 方法名称(参数列表) {
// 方法体
}

注意事项:
对于类、方法来说,abstract关键字和final关键字不能同时使用,因为矛盾。
abstract抽象的,需要被覆盖重写,final不可以改变,不能被重写

public abstract class Fu {public final void method() {System.out.println("父类方法执行!");}public abstract /*final*/ void methodAbs() ;}
public class Zi extends Fu {@Overridepublic void methodAbs() {}// 错误写法!不能覆盖重写父类当中final的方法
//    @Override
//    public void method() {
//        System.out.println("子类覆盖重写父类的方法!");
//    }
}

3、对于修饰局部变量:

public class Demo01Final {public static void main(String[] args) {//基本类型int num1 = 10;System.out.println(num1); // 10num1 = 20;System.out.println(num1); // 20// 一旦使用final用来修饰局部变量,那么这个变量就不能进行更改。// “一次赋值,终生不变”final int num2 = 200;System.out.println(num2); // 200//        num2 = 250; // 错误写法!不能改变!
//        num2 = 200; // 错误写法!// 正确写法!只要保证有唯一一次赋值即可final int num3;num3 = 30;//什么是不可变?// 对于基本类型来说,不可变说的是变量当中的数据不可改变// 对于引用类型来说,不可变说的是变量当中的地址值不可改变,内容可以修改Student stu1 = new Student("赵丽颖");System.out.println(stu1);System.out.println(stu1.getName()); // 赵丽颖stu1 = new Student("霍建华");System.out.println(stu1);//和第一次输出的地址值不一样System.out.println(stu1.getName()); // 霍建华System.out.println("===============");final Student stu2 = new Student("高圆圆");System.out.println(stu1);// 错误写法!final的引用类型变量,其中的地址不可改变
//        stu2 = new Student("赵又廷");//地址值不可以发生改变,但是其中的内容可以发生改变System.out.println(stu2.getName()); // 高圆圆stu2.setName("高圆圆圆圆圆圆");System.out.println(stu2);System.out.println(stu2.getName()); // 高圆圆圆圆圆圆}}

4、成员变量
对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样是不可变。

  1. 由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了。
  2. 对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一。
  3. 必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值。
public class Person {private final String name/* = "鹿晗"*/;//直接赋值public Person() {name = "关晓彤";}//通过构造方法public Person(String name) {this.name = name;}public String getName() {return name;}//    public void setName(String name) {
//        this.name = name;
//    }
}

总结四种权限修饰符

Java中有四种权限修饰符:
public > protected > (default)什么也不写 > private

public protected (default)什么也不写 private
同一个类(我自己) YES YES YES
同一个包(我邻居) YES YES YES
不同包子类(我儿子) YES YES 、 NO NO
不同包非子类(陌生人) YES NO NO

注意事项:(default)并不是关键字“default”,而是根本不写。
protected :对于子女、朋友来说就是public,可以自由使用,没有限制,但是对于外部class没法访问

内部类

分类:

  1. 成员内部类
  2. 局部内部类(包含匿名内部类)

成员内部类

定义

如果一个事物的内部包含另一个事物,那么这就是一个类内部包含另一个类。
例如:身体和心脏的关系。又如:汽车和发动机的关系。

成员内部类的定义格式

修饰符 class 外部类名称 {
修饰符 class 内部类名称 {
// …
}
// …
}

注意:内用外,随意访问;外用内,需要内部类对象。

public class Body { // 外部类public class Heart { // 成员内部类// 内部类的方法public void beat() {System.out.println("心脏跳动:蹦蹦蹦!");System.out.println("我叫:" + name); // 正确写法!}}// 外部类的成员变量private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

使用成员内部类

如何使用成员内部类?有两种方式:

  1. 间接方式:在外部类的方法当中,使用内部类;然后main只是调用外部类的方法。
  2. 直接方式,公式:

类名称 对象名 = new 类名称();
【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】

上述类中Body是外部类,Heart是内部类,间接调用 在外部方法中使用内部类

   // 外部类的方法public void methodBody() {System.out.println("外部类的方法");new Heart().beat();}
public static void main(String[] args) {Body body = new Body();// 通过外部类的对象,调用外部类的方法,里面间接在使用内部类Heartbody.methodBody();}// 按照公式写:Body.Heart heart = new Body().new Heart();heart.beat();

内部类重名变量的访问

// 如果出现了重名现象,那么格式是:外部类名称.this.外部类成员变量名
public class Outer {int num = 10; // 外部类的成员变量public class Inner /*extends Object*/ {int num = 20; // 内部类的成员变量public void methodInner() {int num = 30; // 内部类方法的局部变量System.out.println(num); // 局部变量,就近原则System.out.println(this.num); // 内部类的成员变量//注意:内部类和外部类之间不是继承关系,Inner extends ObjectSystem.out.println(Outer.this.num); // 外部类的成员变量}}}
public class Demo02InnerClass {public static void main(String[] args) {// 外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();Outer.Inner obj = new Outer().new Inner();obj.methodInner();}}

局部内部类:一个类定义在方法的内部

如果一个类是定义在一个方法内部的,那么这就是一个局部内部类。
“局部”:只有当前所属的方法才能使用它,出了这个方法外面就不能用了。

定义格式

修饰符 class 外部类名称 {
修饰符 返回值类型 外部类方法名称(参数列表) {
class 局部内部类名称 {
// …
}
}
}

小节一下类的权限修饰符:
public > protected > (default) > private
定义一个类的时候,权限修饰符规则:

  1. 外部类:public / (default)
  2. 成员内部类:public / protected / (default) / private
  3. 局部内部类:什么都不能写
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();//10 调用了methodOuter方法下面对于//局部内部类中自身方法的调用}}

局部内部类的final问题

如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】。

如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】。备注:从Java 8+开始,只要局部变量事实不变,那么final关键字可以省略。必须是final 原因:
1. new出来的对象在堆内存当中。
2. 局部变量是跟着方法走的,在栈内存当中。
3. 方法运行结束之后,立刻出栈,局部变量就会立刻消失。
4. 但是new出来的对象会在堆当中持续存在,直到垃圾回收消失。也就是说创建出来的MyInner对象存活时间更长,num局部变量会在方法运行结束时消失,只要保证是final,会被直接复制过来,num消失与否不重要,不变最重要!public class MyOuter {public void methodOuter() {final int num = 10; // 所在方法的局部变量,不能改变//java8之后可以不写finalclass MyInner {public void methodInner() {System.out.println(num);}}//复习一下:局部内部类中的方法只有自己可以调用!MyInner inner = new MyInner();inner.methodInner();}public static void main(String[] args) {MyOuter my = new MyOuter();my.methodOuter();//10}
}

匿名内部类:

如果接口的实现类(或者是父类的子类)只需要使用唯一的一次,
那么这种情况下就可以省略掉该类的定义,而改为使用【匿名内部类】。

匿名内部类的定义格式:

接口名称 对象名 = new 接口名称() {
// 覆盖重写所有抽象方法
};

对格式“new 接口名称() {…}”进行解析:

  1. new代表创建对象的动作
  2. 接口名称就是匿名内部类需要实现哪个接口
  3. {…}这才是匿名内部类的内容
    另外还要注意几点问题:
  4. 匿名内部类,在【创建对象】的时候,只能使用唯一一次。
    如果希望多次创建对象,而且类的内容一样的话,那么就需要使用单独定义的实现类了。
  5. 匿名对象,在【调用方法】的时候,只能调用唯一一次。
    如果希望同一个对象,调用多次方法,那么必须给对象起个名字。
  6. 匿名内部类是省略了【实现类/子类名称】,但是匿名对象是省略了【对象名称】
    强调:匿名内部类和匿名对象不是一回事!!!
public class DemoMain {public static void main(String[] args) {
//        MyInterface obj = new MyInterfaceImpl(); //多态写法
//        obj.method1();//        MyInterface some = new MyInterface(); // 错误写法!//         使用匿名内部类,但不是匿名对象,对象名称就叫objA,直接new接口MyInterface objA = new MyInterface() { //大括号后面就是没有名字的类,// 匿名内部类,省去了覆盖重写接口的类@Overridepublic void method1() {System.out.println("匿名内部类实现了方法!111-A");}@Overridepublic void method2() {System.out.println("匿名内部类实现了方法!222-A");}};objA.method1();objA.method2();System.out.println("=================");//注意:objA对象只能用一次// 使用了匿名内部类,而且省略了对象名称,也是匿名对象。 new 接口().方法new MyInterface() { //此大括号既是匿名内部类也是匿名对象@Overridepublic void method1() {System.out.println("匿名内部类实现了方法!111-B");}@Overridepublic void method2() {System.out.println("匿名内部类实现了方法!222-B");}}.method1();// 因为匿名对象无法调用第二次方法,所以需要再创建一个匿名内部类的匿名对象new MyInterface() {@Overridepublic void method1() {System.out.println("匿名内部类实现了方法!111-B");}@Overridepublic void method2() {System.out.println("匿名内部类实现了方法!222-B");}}.method2();}}

引用类型方法总结

类作为成员变量类型:

// 游戏当中的英雄角色类
public class Hero {//String不是基本类型//Ctrl 点击String 就能发现String其实是一个类,name的类型就是String,// 那么我们就可以自己创建类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 attack() {System.out.println("年龄为" + age + "的" + name + "用" + 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;}
}
//创建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(20);// 创建一个武器对象Weapon weapon = new Weapon("AK-47");// 为英雄配备武器hero.setWeapon(weapon);// 年龄为20的盖伦用多兰剑攻击敌方。hero.attack();}}

说明:我们的成员变量不光能用基本类型,还可以用我们自己创建的class

接口作为成员变量类型:

//定义接口Skill
public interface Skill { void use(); // 释放技能的抽象方法}
public class SkillImpl implements Skill {@Overridepublic void use() {System.out.println("Biu~biu~biu~");}
}
public class Hero {private String name; // 英雄的名称private Skill 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 void setName(String name) {this.name = name;}public Skill getSkill() {return skill;}public void setSkill(Skill skill) {this.skill = skill;}
}
public class DemoGame {public static void main(String[] args) {Hero hero = new Hero();hero.setName("艾希"); // 设置英雄的名称// 设置英雄技能
//        hero.setSkill(new SkillImpl()); // 使用单独定义的实现类// 还可以改成使用匿名内部类
//        Skill skill = new Skill() {
//            @Override
//            public void use() {
//                System.out.println("Pia~pia~pia~");
//            }
//        };
//        hero.setSkill(skill);// 进一步简化,同时使用匿名内部类和匿名对象hero.setSkill(new Skill() {@Overridepublic void use() {System.out.println("Biu~Pia~Biu~Pia~");}});hero.attack();}
}

接口作为方法的参数和返回值:

一定注意:List和ArrayList要进行导包!

/*
java.util.List正是ArrayList所实现的接口。*/
public class DemoInterface {public static void main(String[] args) {// 左边是接口名称,右边是实现类名称,这就是多态写法List<String> list = new ArrayList<>();//List是接口//多态(左父右子) list是List<String>类型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("迪丽热巴");list.add("古力娜扎");list.add("玛尔扎哈");list.add("沙扬娜拉");return list;}}

基础06final、权限、内部类相关推荐

  1. 专题开发十二:JEECG微云快速开发平台-基础用户权限

      专题开发十二:JEECG微云快速开发平台-基础用户权限 11.3.4自定义按钮权限 Jeecg中,目前按钮权限设置,是通过对平台自己封装的按钮标签(<t:dgFunOpt等)进行设置.而在开 ...

  2. 开发指南专题十一:JEECG微云快速开发平台--基础用户权限

     开发指南专题十一:JEECG微云快速开发平台--基础用户权限    11.1. 权限设计 基本概念 权限管理模块涉及到的实体有:用户.角色和系统资源(包括系统菜单.页面按钮等).用户可以拥有多个 ...

  3. 前后端分离(SpringBoot+Vue)-基础的权限管理系统

    前后端分离(SpringBoot+Vue)-基础的权限管理系统 简介 前端项目代码地址:前端代码 后端项目代码地址:后端代码 最后的附录记录了自己在开发过程遇到问题及实现.部分文件的介绍 采用前后端分 ...

  4. 专题开发十二:JEECG微云高速开发平台-基础用户权限

      专题开发十二:JEECG微云高速开发平台-基础用户权限 11.3.4自己定义button权限 Jeecg中.眼下button权限设置,是通过对平台自己封装的button标签(<t:dgFun ...

  5. Java基础篇:内部类详解

    目录: 一.内部类的好处: 二.成员内部类: 三.局部内部类: 四.静态内部类: 五.匿名内部类: 六.总结: 内部类:可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一个编译时概念 ...

  6. Java基础--访问权限控制符

    今天我们来探讨一下访问权限控制符. 使用场景一:攻城狮A编写了ClassA,但是他不想所有的攻城狮都可以使用该类,应该怎么办? 使用场景二:攻城狮A编写了ClassA,里面有func1方法和func2 ...

  7. 【JAVA基础篇】内部类

    定义在一个类内部的类称为内部类.内部类访问权限可以是public.protected.default或private,可以声明为abstract供其他内部类或外部类继承,可以声明为static.fin ...

  8. linux修改文件权限的命令_Linux基础文件权限管理

    图片来源:pexels.com 你好,我是goldsunC 让我们一起进步吧! Linux文件属性 文件权限在Linux基础中是一个很重要的概念,一个系统管理员应该熟练掌握文件权限的概念.OK,现在我 ...

  9. Java 基础巩固:内部类的字节码学习和实战使用场景

    文章出自:安卓进阶学习指南 主要贡献者: Cloud9527 Alex_赵 Struggle shixinzhang 读完本文你将了解: 背景介绍 四种内部类介绍 成员内部类 静态内部类 局部内部类 ...

最新文章

  1. 自动化测试有缺点吗?
  2. 破解MS Word 的只读密码限制
  3. uva 11584——Partitioning by Palindromes
  4. LeetCode题 - 83. 删除排序链表中的重复元素 python实现
  5. java sessionid放入cookie_JAVA开发 SESSION和COOKIE的关系
  6. 正态分布的前世今生:正态魅影
  7. 基于51单片机直流电机PWM控制器设计
  8. 如何看待越来越多年轻人追捧「摸鱼哲学」,拒绝努力的年轻人真比老一辈活得更通透吗?
  9. Adobe Acrobat XI Pro 软件下载安装详细教程
  10. Xtend:Android平台的Swift语言
  11. 《笑傲江湖》人名解读
  12. RocketMQ可视化Web管理界面
  13. 【00】processing-历史(中文)
  14. 在 ionic 项目中使用(迁移) capacitor
  15. jQuery的$工具方法和属性
  16. python生成漂亮桌面背景心灵鸡汤可每日学英语
  17. [药品飞检]六大部门检查要点(38个子项目)
  18. unity地面添加材质球_为Unity3D创建素材(1):图片、着色器、材质球
  19. 单片机毕设分享100例(五)
  20. 麒麟系统启用SELinux

热门文章

  1. java制作扫雷游戏中埋雷的难点_java 扫雷游戏源码案例项目
  2. LeetCode-124.二叉树中的最大路径和
  3. 境内银行卡磁条信息格式
  4. Java中transientkeyword的应用
  5. codeforces 580C Kefa and Park(DFS)
  6. 注入攻击-SQL注入和代码注入
  7. php利用反射机制查找类和方法的所在位置
  8. LA3485二分+求解积分方程+辛普森算法计算积分
  9. 第二个结对编程——UI设计
  10. jmu-python-函数-找钱_6-1 jmu-python-杨辉三角