【Java SE】基础知识回顾——【7.Final | 权限 | 内部类】

Final,权限,内部类

Final关键字的概念和四种用法

修饰类
package Demo01;

/**
 * @author 270
 * 当final关键字用来修饰一个类的时候,格式:
 * public final class 类名称{
 *     //...
 * }
 * 含义:当前的类不能有任何的子类
 *       不能使用一个final类来作为父类
 *【注意】:一个类如果是final的,那么所有其中的成员方法都无法进行覆盖重写(因为没有子类)
 */
public final class MyClass extends Object{
    public void method(){
        System.out.println("方法执行!");
    }
}
修饰成员方法
package Demo01;

/**
 * @author 270
 * 当final关键字修饰一个方法时,这个方法就是最终方法。也就是不能被覆盖重写
 * 格式:
 * 修饰符 final 返回值类型 方法名称(参数列表){
 *     //方法体
 * }
 * 注意事项:
 * 对于类,方法来说,abstract关键字和final关键字不能同时使用,因为矛盾
 */
public abstract class Fu {
    public  final void method(){
        System.out.println("父类方法已执行");
    }
    public abstract /*final*/ void methodabs();

}
package Demo01;

/**
 * @author 270
 */
public abstract class Zi extends Fu{
    //错误写法:
    // @Override
    //public void method(){
    //    System.out.println("覆盖重写父类方法");
    //}


}
修饰局部变量
package Demo01;

/**
 * @author 270
 * final代表最终的,不可改变的
 * 

* 常见用法: * 1.修饰类 * 2.修饰方法 * 3.修饰局部变量 * 4.修饰成员变量 */ public class Demo01Final { public static void main(String[] args) { int num1 = 10; System.out.println(num1); num1 = 20; System.out.println(num1); //一旦用final修饰,变量值无法改变 //这里是指变量当中的数据不可变 final int num2 = 200; //对于引用类型来说,不可变说的是变量当中的地址值不可改变 Student stu1 = new Student("270"); System.out.println(stu1); System.out.println(stu1.getName()); stu1 = new Student("2770"); System.out.println(stu1); System.out.println(stu1.getName()); System.out.println("=============="); final Student stu2 = new Student("999"); System.out.println(stu2); System.out.println(stu2.getName()); //错误写法:已经用了final关键字修饰,其地址不可改变 // stu2 = new Student("2312"); stu2.setName("99999"); System.out.println(stu2); System.out.println(stu2.getName()); } }

修饰成员变量
/**
 * @author 270
 * 对于成员变量来说,如果使用final关键字修饰,那么这个变量也照样不可变
 * 1.由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了
 * 2.对于final的成员变量,要么使用直接赋值,要么使用构造方法赋值。二者选其一
 * 3.必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值
 */
public class Person {

    private final String name;
    //直接赋值
    //private final String name= "21";

    public Person(String name) {
        this.name = name;
    }

    public Person() {
        //另一种赋值,用构造方法赋值
        name = "21";
    }

    public String getName() {
        return name;
    }
    //这里将Setter注释掉的原因:
    //final关键字修饰,所以不能被赋值,所以将其注释掉
    //  public void setName(String name) {
    //    this.name = name;
    // }
}
四种权限修饰符号
* Java的四种权限修饰符
*              public > protected > (default) > private
* 同一个类     YES       YES        YES         YES
* 同一个包     YES       YES        YES         NO
* 不同包子类   YES       YES        NO          NO
* 不同包非子类 YES       NO         NO          NO
*
*【注意】:(default)并不是关键字,而是不写
定义成员内部类
/**
 * @author 270
 * 如果一个事物的内部包含另一个事物没那么就是一个类内部包含另一个类
 * 

* 分类: * 1.成员内部类 * 2.局部内部类(包含匿名内部类) * * 成员内部类的定义格式: * 修饰符 class 外部类名称{ * 修饰符 class 内部类名称{ * //... * } * //... * } *【注意】:内用外,随意访问;外用内,需要借助内部类对象 */ package Demo03; /** * @author 270 */ public class Body {//外部类 private String name; public class Heart {//成员内部类 //内部类方法 public void beat() { System.out.println("跳动"); System.out.println("我叫" + name); } } public void methodBody() { System.out.println("外部类的方法"); } }

内部类的使用方法
**
 * @author 270
 * 如果一个事物的内部包含另一个事物没那么就是一个类内部包含另一个类
 * <p>
 * 分类:
 * 1.成员内部类
 * 2.局部内部类(包含匿名内部类)
 * <p>
 * 成员内部类的定义格式:
 * 修饰符 class 外部类名称{
 * 修饰符 class 内部类名称{
 * //...
 * }
 * //...
 * }
 * 【注意】:内用外,随意访问;外用内,需要借助内部类对象
 * ===================
 * 如何使用成员内部类?有两种方式
 * 1.间接方式:在外部类的方法中,使用内部类,然后只是调用外部类的方法。
 * 2.直接方式:公式:
 * 类名称 对象名 = new 类名称();
 * 【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】
 */
public class Demo01InnerClass {
    public static void main(String[] args) {
        Body body = new Body();
        //通过外部类的对象,调用外部类的方法,里面间接使用内部类
        body.methodBody();
        System.out.println("=================");\
        //按照公式写,这样不用创建外部类对象
        Body.Heart heart = new Body().new Heart();
        heart.beat();
    }
}

内部方法的同名变量访问

外部,内部类
/**
 * @author 270
 * 如果出现了重名现象,那么格式是:
 * 【格式】:外部类名称.this.外部类成员变量名
 */
public class Outer {
    int num = 10;
    //外部成员变量

    public class Inner {
        int num = 20;
        //内部成员变量
        public void methodInner(){
            //内部方法的局部变量
            int num = 30;
            System.out.println(num);//局部变量,就近原则
            System.out.println(this.num);//内部类的成员变量
            System.out.println(Outer.this.num);//外部类的成员变量
        }
    }
}
主程序
package Demo03;

/**
 * @author 270
 * 如果一个事物的内部包含另一个事物没那么就是一个类内部包含另一个类
 * 

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

* 成员内部类的定义格式: * 修饰符 class 外部类名称{ * 修饰符 class 内部类名称{ * //... * } * //... * } * 【注意】:内用外,随意访问;外用内,需要借助内部类对象 * =================== * 如何使用成员内部类?有两种方式 * 1.间接方式:在外部类的方法中,使用内部类,然后只是调用外部类的方法。 * 2.直接方式:公式: * 类名称 对象名 = new 类名称(); * 【外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();】 */ public class Demo01InnerClass { public static void main(String[] args) { Body body = new Body(); //通过外部类的对象,调用外部类的方法,里面间接使用内部类 body.methodBody(); System.out.println("================="); //按照公式写,这样不用创建外部类对象 Body.Heart heart = new Body().new Heart(); heart.beat(); } } 运行结果————————> 30 20 10

局部内部类的定义

主方法
package Demo04;

/**
 * @author 270
 */
public class DemoMain {
    public static void main(String[] args) {
        Outer obj = new Outer();
        /**因为Inner是局部内部类
         * 所以无法在它存在的类以外的位置调用
         * 所以需要自己在Outer类中调用好
         * 之后在主程序中调用外部方法
         * 这样才能调用到局部内部类的方法
        */
        obj.methodOuter();

    }
}
局部内部类
package Demo04;

/**
 * @author 270
 * 如果一个类是定义在一个【方法】内部的,那么这就是一个局部内部类
 * "局部",只有当前所属的方法才能使用它,出了这个方法外面就不能用了。
 * 【定义格式】:
 * 修饰符 class 外部类名称{
 *       修饰符 返回值类型 外部类方法名称(参数列表){
 *                class 局部内部类名称
 *                         //...
 *                }
 *       }
 *
 *小结:【类】的修饰符
 * public > protected > (default) > private
 * 1.外部类:public/(default)
 * 2.成员内部类:public/protected/(default)/private
 * 3.局部内部类:什么都不能写
 */
//外部类
public class Outer {
    
    //外部类方法
    public void methodOuter() {
        
        //局部内部类
        class Inner {
            int num = 10;
            
            //局部内部类方法
            public void methodInner() {
                System.out.println(num);
            }
        }
        Inner inner = new Inner();
        inner.methodInner();
    }

}

局部内部类的final问题

package Demo04;

/**
 * @author 270
 * 局部内部类,如果希望访问所在方法的局部变量,那么这个局部变量必须是【有效final的】
 *
 * 备注:只要局部变量事实不变,那么final关键字可以省略
 *
 * 原因:
 * 1.new出来的对象在堆内存中。
 * 2.局部变量是跟着方法走的,在栈内存当中。
 * 3.方法运行结束之后,立刻出栈,局部变量就会立刻消失
 * 4.但是new出来的对象在堆当中持续存在,直到垃圾回收消失
 */
public class MyOuter {
    public void methodOuter() {
        final int num = 10;
        //所在方法的局部变量

        class MyInner {
            public void methodInner(){
                System.out.println(num);
            }
        }
    }
}

匿名内部类

package Demo01;

/**
 * @author 270
 * 如果接口的实现类,或是父类的子类,只需要使用一次
 * 那么这种情况下就可以省略掉该类的定义,改用【匿名内部类】
 * 

* 匿名内部类的格式: * 接口名称 对象名 = new 接口名称():{ * //覆盖重写所有抽象方法 * }; * 【注意】:最后的大括号后面有一个分号 *

*

* 对格式进行解析"new 接口名称(){...}"进行解析 * 1.new代表创建对象的动作 * 2.接口名称就是匿名内部类需要实现那个接口 * 3.{...}这才是匿名内部类的内容 *

* 另外注意的问题: * 1.匿名内部类:在创建对象的时候,只能使用唯一一次, * 不能重复用同一个对象调用两次方法,如果希望多次创建对象,而且类的内容一样的话 * 那没就必须使用单独定义的实现类了 * 2.匿名对象,在【调用方法】的时候,只能调用唯一一次 * 如果希望同一个对象,调用多次方法,那么必须给这个对象起名字 * 3.匿名内部类是省略了【实现类/子类】,但是匿名对象是省略了【对象名称】 * 【强调】:匿名内部类和匿名对象不是一回事 */ public class DemoMain { public static void main(String[] args) { MyInterface impl = new MyInterface() { @Override public void method1() { System.out.println("匿名内部类实现了方法 111-A"); } @Override public void method2() { System.out.println("匿名内部类实现了方法 222-A"); } }; impl.method1(); impl.method2(); System.out.println("================="); //使用了匿名内部类,而且省略了对象名称,也是匿名对象 new MyInterface() { @Override public void method1() { System.out.println("匿名内部类实现了方法 111-B"); } @Override public void method2() { System.out.println("匿名内部类实现了方法 222-B"); } }.method1(); //因为匿名对象无法调用第二次方法,所以需要再创建一个新的匿名内部类的匿名对象 } }

类作为成员变量类型

hero类
package Demo01;

/**
 * @author 270
 */
public class Hero {
    private String name;
    private Weapon weapon;
    private int age;

    public Hero(){

    }

    public Hero(String name, Weapon weapon, int age) {
        this.name = name;
        this.weapon = weapon;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Weapon getWeapon() {
        return weapon;
    }

    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    public void attack(){
        System.out.println("年龄为"+age+"的"+name+"正在用"+weapon.getCode()+"攻击XXX");
    }
}
Weapon类作为成员变量
package Demo01;

/**
 * @author 270
 */
public class Weapon {
    private String code;
    //武器代号

    public Weapon(String code) {
        this.code = code;
    }

    public Weapon() {
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}
主程序
package Demo01;

/**
 * @author 270
 */
public class DemoHero {
    public static void main(String[] args) {
        Hero hero = new Hero();
        hero.setName("厄斐琉斯");
        hero.setAge(23);

        //创建一个武器对象
        Weapon weapon = new Weapon("断魂");

        //为英雄配备武器
        hero.setWeapon(weapon);
        hero.attack();

    }
}

接口作为成员变量

接口
package Demo02;

/**
 * @author 270
 */
public interface Skill {
    void use();
}
Hero类
package Demo02;

/**
 * @author 270
 */
public class Hero {
    private String name;
    private Skill skill;

    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 Hero() {
    }

    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;
    }
}
主程序
package Demo02;

/**
 * @author 270
 */
public class DemoMain {
    public static void main(String[] args) {
        Hero hero = new Hero();
        hero.setName("厄斐琉斯");

        //设置英雄技能,方法一,使用单独定义的实现类
        hero.setSkill(new SkillImpl());
        hero.attack();
        //设置英雄技能,方法二,使用匿名内部类
        Skill skill = new Skill() {
            @Override
            public void use() {

            }
        };
        hero.setSkill(skill);
        hero.attack();
        //设置英雄技能,方法三,进一步简化
        hero.setSkill(new Skill() {
            @Override
            public void use() {

            }
        });
        hero.attack();

    }
}

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

package Demo02;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 270
 * java.util.list正是Arraylist所实现的接口。
 *这里的List接口作为返回值类型
 */
public class DemoInterface {
    public static void main(String[] args) {
        //左边是接口名称,右边是实现类名称,这就是多态写法
        List<String> list = new ArrayList<>();
        List<String> result = addNames(list);
        for (int i = 0; i < list.size(); i++) {
            System.out.println(result.get(i));
        }
    }

    public static List<String> addNames(List<String> list){
        list.add("厄斐琉斯");
        list.add("清辉曳宁");
        return list;
    }
}

随机发红包的代码(4/18)

package Demo03;

import java.util.ArrayList;
import java.util.Random;

/**
 * @author 270
 */
public class RandomModel implements OpenMode{
    @Override
    public ArrayList<Integer> divide(int totalMoney, int totalCount) {
        ArrayList<Integer> list = new ArrayList<>();
        /**
         * 随机分配
         * 最少一分钱
         * 最多不超过剩下金额平均数的2倍
         *
         * 范围公式是:1+random.nextInt(leftMoney/leftCount*2)
         */
        Random r = new Random();
        int leftMoney = totalMoney;
        int leftCount = totalCount;
        /**
         * total不变
         * left变
         * 随机发前n-1个,最后一个不用随机
         */

        for (int i =0;i< totalCount-1;i++){
             int money = r.nextInt(leftMoney/leftCount*2)+1;
             list.add(money);
             leftMoney -= money;
             leftCount--;
        }
        list.add(leftMoney);

        return null;
    }
}

文章目录

    • Final,权限,内部类
      • Final关键字的概念和四种用法
        • 修饰类
        • 修饰成员方法
        • 修饰局部变量
        • 修饰成员变量
        • 四种权限修饰符号
        • 定义成员内部类
        • 内部类的使用方法
      • 内部方法的同名变量访问
        • 外部,内部类
        • 主程序
      • 局部内部类的定义
          • 主方法
        • 局部内部类
      • 局部内部类的final问题
      • 匿名内部类
      • 类作为成员变量类型
        • hero类
        • Weapon类作为成员变量
        • 主程序
      • 接口作为成员变量
        • 接口
        • Hero类
        • 主程序
      • 用接口作为方法的参数和返回值
      • 随机发红包的代码(4/18)

你可能感兴趣的:(Java,基础,java,开发语言)