Tips:样式蚂蚁森林浇水get

java基础——day09-1 final、权限、内部类、引用类型

final关键字

概述:

  final:不可以改变。用于修饰类、方法、变量(成员变量、局部变量)

  特点:

  1.类:被修饰的类,不能被继承

  2.方法:被修饰的方法,不能被重写

  3.变量:被修饰的变量,不能重新赋值

使用方式:

1.修饰类(不能被继承)

  含义:当前类不能有任何子类但是一定有父类(所有类 默认的父类是Object)

  格式:public final class 类名{} 

package day10.day10_1;
//final关键字 修饰类
public final class Myclass {
    //里面的变量和方法 该怎么写就怎么写
    int number = 10;
    public void method(){
        System.out.println("this is final class");
    }
}
final修饰类(不能被继承)

  用途:String类、Math类、Scanner类等,都是被final修饰的,目的在于供我们使用,而不让我们改变内容。

  注意:一个类,如果被final修饰,那么其中的所有的成员方法都无法覆盖重写

2.修饰方法(不能被重写)

  含义:当一个final修饰一个方法,那么这个方法是最终方法,不能被覆盖重写。  

  格式:修饰符 final 返回值类型 方法名(参数列表) {}

package day10.day10_1.day10_2;

public class Fu {
    public  void method(){
        System.out.println("父类方法执行");
    };
    //定义final修饰的方法
    public final void methodA(){
        System.out.println("被final修饰的父类方法");
    }
}
Fu
package day10.day10_1.day10_2;

public class Zi extends Fu {
    @Override
    public void method() {
        //覆盖重写父类method方法
        System.out.println("父类方法重写");
    }
//    public void methodA(){
//        System.out.println("错误写法");
//    }
}
Zi
package day10.day10_1.day10_2;

public class demo {
    public static void main(String[] args) {
        Zi son = new Zi();
        son.method();
        //子类任然可以调用父类final修饰的成员方法
        son.methodA();
    }
}
main

  注意:

  1.final修饰的父类成员方法,虽不能被重写,但是子类对象还是可以调用,因为子类对象没有,会向上找。

  2.对于类、方法来说,abstractfinal关键字不能同时使用,因为矛盾。(abstract一定要覆盖重写 final一定不能覆盖重写

3.修饰变量(不能被重新赋值)

  1、局部变量——基本类型

  基本类型的局部变量,被final修饰后,只能赋值一次,不能再更改,例如:

package day10.day10_1.day10_2;

public class demo01 {
    public static void main(String[] args) {
        final int num; //声明变量 final修饰
        num = 10;   //第一次赋值
        //num = 20;   //第二次赋值 报错
    }
}
final修饰局部变量

  提问:那么如何通过编译?

package day10.day10_1.day10_2;

public class demo01 {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
           final int num = i;
            System.out.println(num);
        }
    }
}
利用for反复给final变量赋值

  2、局部变量——引用类型

  引用类型的局部变量,被final修饰后,只能指向一个对象地址不能再更改。但是不影响对象内部成员变量值的修改

package day10.day10_1.day10_3;

public class User {
    private String name;
    //构造方法
    public User() {}

    public User(String name) {
        this.name = name;
    }
    //get & set
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    //成员方法

}
User类
package day10.day10_1.day10_3;

public class demo {
    public static void main(String[] args) {
        //创建User对象
        User user = new User("赵丽颖");
        System.out.println(user.getName());//赵丽颖
        System.out.println(user); //User@452b3a41

        //改变的是其地址值
        user = new User("冯绍峰");
        System.out.println(user.getName());//冯绍峰
        System.out.println(user); //User@4a574795
        System.out.println("===================");
        final User user1 = new User("刘亦菲");
        System.out.println(user1);
//        user1 = new User("胡歌"); 错误写法 fianl变量引用类型 不可改变
        user1.setName("胡歌");
        System.out.println(user1);
        System.out.println(user1.getName()); //胡歌 地址值一样
    }
}
main

  3、成员变量

  1.成员变量涉及到初始化问题,初始化方式有两种,二选一

  2.成员变量具有默认值,所以用了final后,必须手动赋值

  a、显示初始化(直接赋值)

  

 

 

  b、构造方法初始化(构造方法里赋值)

 

 

 

 

 

权限修饰符

概述

  Java中提供了四种访问权限,使用不同访问权限修饰符被修饰的内容会有不同的访问权限

  1.public:公共的

  2.protected:受保护的

  3.default:默认的

  4.private:私有的

不同权限的访问能力

   public具有最大权限,private最小访问权限。

  使用权限建议:

  1.成员变量使用private,隐藏细节

  2.构造方法使用public,方便创建对象

  3.成员方法使用public,方便调用方法

内部类

概述

1.什么是内部类

  将一个类A 定义在 另一个类B中,则类A称为内部类,B则称为外部类

  例如:身体和心脏的关系,汽车和发动机引擎的关系

成员内部类与局部内部类

1.成员内部类

  定义格式:

  

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

package day10.day10_1.day10_5;

public class body { //外部类

    public class heart{ //定义成员内部类
        //内部类的成员方法
        public void methodHeart(){
            System.out.println("心脏跳动");
            System.out.println("我叫"+name); //可以访问 正确写法
        }
    }

    //外部类的成员变量
    private String name;
    //外部类的成员方法
    public void methodBody(){
        System.out.println("外部类方法");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
内部类--body$heart

  如何使用内部类:

  1.间接使用:外部内的方法中使用内部类,然后main方法只是调用外部类的方法

package day10.day10_1.day10_5;

public class body { //外部类

    public class heart{ //定义成员内部类
        //内部类的成员方法
        public void methodHeart(){
            System.out.println("心脏跳动");
            System.out.println("我叫"+name); //可以访问 正确写法
        }
    }

    //外部类的成员变量
    private String name;
    //外部类的成员方法
    public void methodBody(){
        System.out.println("外部类方法");
        //间接使用
        heart xinzang = new heart();
        xinzang.methodHeart();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
含内部类的-body
package day10.day10_1.day10_5;

import day10.day10_1.day10_4.Person;

public class demo {
    public static void main(String[] args) {
        body Person = new body();
        Person.setName("张一山"); //外部类的set方法

        //接见使用内部类
        Person.methodBody();
    }
}
main

  2.直接使用:

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

package day10.day10_1.day10_5;

public class body { //外部类

    public class heart{ //定义成员内部类
        //内部类的成员方法
        public void methodHeart(){
            System.out.println("心脏跳动");
            System.out.println("我叫"+name); //可以访问 正确写法
        }
    }

    //外部类的成员变量
    private String name;
    //外部类的成员方法
    public void methodBody(){
        System.out.println("外部类方法");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
含内部类的类—body
package day10.day10_1.day10_5;

import day10.day10_1.day10_4.Person;

public class demo {
    public static void main(String[] args) {
        //直接使用
        body.heart person = new body().new heart();
//        person.setName = "错误写法" 内部类没法调用外部类的成员方法
        person.methodHeart();

    }
}
main

  注意:使用内部类new出来的对象 没办法访问外部类的成员方法。

  3.内部类成员变量同名问题

package day10.day10_1.day10_5;

public class Outer {//外部类
    int num = 10;   //外部类成员变量
    
    public class Inner{//内部类
        int num = 20;
        public void method(){//内部类的成员方法
            int num = 30;
            System.out.println(num);    //就近原则 输出30
            System.out.println(this.num);   //内部类的成员变量 20
//            System.out.println(super.num); 错误写法 因为内部类不是外部类 心脏不是身体
            System.out.println(Outer.this.num);//外部的成员变量 10
            
        }
    }
    
}
重名的成员变量
package day10.day10_1.day10_5;

public class demo01 {
    public static void main(String[] args) {
        //创建直接访问内部类的对象
        Outer.Inner Test = new Outer().new Inner();
        Test.method();
    }
}
main

  在 内部类中 访问 外部类成员变量,使用:外部类.this.成员变量名

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

  定义:如果一个类 定义在一个 方法内部,那么它就是一个局部类。

  格式:

  修饰符 class 外部类名称{

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

    修饰符 class 局部内名称

                       }

              }

 

  例如:需要简介访问

package day10.day10_1;

public class outer {//外部类
    //外部成员方法
    public void methodOuter(){
        class Inner{//局部内部类
            int num = 10;
            public void methodInner(){
                System.out.println(num); //10
            }
        }
        //间接使用
        Inner inner = new Inner();
        inner.methodInner();
    }
}
局部内部类
package day10.day10_1;

public class demo {
    public static void main(String[] args) {
        //创建外部类对象
        outer duixiang = new outer();
        duixiang.methodOuter();
    }
}
main

  使用权限建议:

  1.外部类:public / default

  2.内部类:public / protected / default / private

  3.局部内部类:什么修饰符都不写

3.匿名内部类(最重要)

  如果接口的实现类(父类的子类)只需要使用唯一的一次[就new 的那一次]

  那么这种情况下可以省略掉类的定义,而改为【匿名内部类】

  定义格式:

  接口名称 对象名 = new 接口名称(){

  //覆盖重写接口中的所有抽象方法 };

  例如:

package day10.day10_1;

public interface MyInterface {
    void method();
}
interface
package day10.day10_1;

import day09.day08_1.day08_2.Myinterface;

public class demo {
    public static void main(String[] args) {
        //匿名局部内部类
        Myinterface duixiang = new Myinterface() {
            @Override
            public void method() {
                System.out.println("匿名内部类 实现了方法");
            }
        };
        //调用匿名内部类
        duixiang.method();
    }
}
匿名内部类(定义和使用)

  注意事项:

  1、对 “new 接口名称(){....}” 的解释

    1.new 代表创建对象

    2.接口名称:就是匿名内部类需要实现哪个接口

    3.{...}:匿名内部类的内容

  2、匿名内部类使用注意事项

    1.匿名内部类,在创建对象时,只能使用唯一 一次。用一次 new接口名称{}  一次

      如果希望多次创建对象,而且类的内容一样,就必须使用实现类。

    2.匿名对象

    匿名内部类:Interface obj = new Interface{...};

          obj.匿名方法

    匿名对象:new interface{....}.匿名方法;

    所以匿名对象 只能调用一次匿名方法 再次使用 需要重写new

    3.匿名内部类时省略了实现类(子类),匿名对象省略了对象名称。

引用类型用法总结

概述:

  实际开发中,引用类型的使用十分重要,也十分普遍。

  基本类型可以作为成员变量,作为方法的参数,那么引用类型也是可以的。

class作为成员变量

  例如:将英雄单独为一类,其包含英雄的基本属性,再单独定义一个武器类,武器类作为成员变量提供给英雄使用

package day11;
//定义英雄类
public class Hero {
    private String name;//定义英雄名字
    private int age;//定义英雌年龄
    private weapons weapon;//使用武器类作为成员变量

    //成员方法
    public void attack(){
        //class作为成员变量 在调用的时候 还是需要使用get方法
        System.out.println(age+"岁的英雄"+name+",正使用"+weapon.getWeaponName()+"攻击敌人!");
    }
    //构造方法
    public Hero() {
    }

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

    //get & set 方法
    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 weapons getWeapon() {
        return weapon;
    }

    public void setWeapon(weapons weapon) {
        this.weapon = weapon;
    }
}
Hero类
package day11;
//定义英雄武器类
public class weapons {
    private String weaponName;

    public weapons(){}
    public weapons(String weaponName) {
        this.weaponName = weaponName;
    }
    public String getWeaponName() {
        return weaponName;
    }

    public void setWeaponName(String weaponName) {
        this.weaponName = weaponName;
    }
}
武器类
package day11;

public class demo {
    public static void main(String[] args) {
        //创建 hero对象
        Hero hero = new Hero();
        //设置英雄的姓名和年龄
        hero.setName("马冬梅");
        hero.setAge(18);
        //创建英雄武器
        weapons tools = new weapons();
        tools.setWeaponName("拖鞋");
        hero.setWeapon(tools);

        hero.attack();
    }
}
main

  类作为成员变量时,对他进行赋值操作,实际上是赋值给 该类的一个对象。

Interface作为成员变量

  接口是对方法的封装,对应游戏当中,可以看做角色的扩展技能。

  例如:

package day11.day11_1;

public interface Skill {
    public abstract void use();//释放技能的抽象方法
}
Interface—Skill
package day11.day11_1;

public class Hero {
    //成员变量
    private String name;
    private Skill skill;

    //构造方法
    public Hero() {}
    public Hero(String name, Skill skill) {
        this.name = name;
        this.skill = skill;
    }
    //成员方法
    public void attacked(){
        System.out.print(name+"正在释放技能:");
        skill.use();
        System.out.print(",攻击敌人");
    }

    //get & set 方法
    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;
    }
}
Hero类
package day11.day11_1;

public class Game {
    public static void main(String[] args) {
        Hero hero = new Hero();
        hero.setName("艾希");
        //设置英雄 可以使用实现类 也可以使用匿名内部类
        Skill skill = new Skill() {
            @Override
            public void use() {
                System.out.print("穿云箭");
            }
        };
        hero.setSkill(skill);
        hero.attacked();
        System.out.println("\n==============================");
        //使用匿名内部类和匿名对象
        hero.setSkill(new Skill() {
            @Override
            public void use() {
                System.out.print("急速攻击");
            }
        });


        hero.attacked();
    }
}
main

  设计接口作为成员变量,增强了程序的灵活性和可扩展性。

  接口作为成员变量时,对它进行赋值的操作,实质上是赋给它 该类接口的 一个子类对象

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

  java.util.list正是ArrayList所实现的接口。

package day11.day11_2;

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

public interface Myinterface {
    public static List<Integer> getEvenNum(List<Integer> list){
        //创建保存偶数的集合
        ArrayList<Integer> evenList = new ArrayList<>();
        //变量list 判断偶数元素 并添加到evenList中
        for (int i = 0; i < list.size(); i++) {
            if(list.get(i) % 2 ==0){
                evenList.add(list.get(i));
            }
        }
     return evenList;
    }
}
Myinterface
package day11.day11_2;

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

public class demo {
    public static void main(String[] args) {
        ArrayList<Integer> number = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            number.add(i);
        }
        List<Integer>list =  Myinterface.getEvenNum(number);
        System.out.println(list);
    }
}
main

  接口作为参数时,传递的是它的子类对象

  接口作为返回值类型时,返回它的子类对象

 

posted @ 2021-03-10 23:10  心岛未晴  阅读(78)  评论(0)    收藏  举报