Java学习笔记:this、传参、包及访问修饰符

this、传参、包及访问修饰符

  • 学习参考网址https://how2j.cn/p/6235

this

  • this这个关键字,相当于普通话里的“我” 
    • 小明说 “我吃了” 这个时候,“我” 代表小明 
    • 小红说 “我吃了” 这个时候,“我” 代表小红 
  • "我"代表当前人物 
  • this这个关键字,相当于普通话里的“我” 
  • this即代表当前对象
public class Hero {
     
    String name; //姓名
     
    float hp; //血量
     
    float armor; //护甲
     
    int moveSpeed; //移动速度
 
    //打印内存中的虚拟地址
    public void showAddressInMemory(){
        System.out.println("打印this看到的虚拟地址:"+this);
    }
     
    public static void main(String[] args) {
        Hero garen =  new Hero();
        garen.name = "盖伦";
        //直接打印对象,会显示该对象在内存中的虚拟地址
        //格式:Hero@c17164 c17164即虚拟地址,每次执行,得到的地址不一定一样
 
        System.out.println("打印对象看到的虚拟地址:"+garen);
        //调用showAddressInMemory,打印该对象的this,显示相同的虚拟地址
        garen.showAddressInMemory();
         
        Hero teemo =  new Hero();
        teemo.name = "提莫";
        System.out.println("打印对象看到的虚拟地址:"+teemo);
        teemo.showAddressInMemory();
    }  
     
}

  • 通过this访问属性
    • 通过this关键字访问对象的属性
public class Hero {
     
    String name; //姓名
     
    float hp; //血量
     
    float armor; //护甲
     
    int moveSpeed; //移动速度
 
    //参数名和属性名一样
    //在方法体中,只能访问到参数name
    public void setName1(String name){
        name = name;
    }
     
    //为了避免setName1中的问题,参数名不得不使用其他变量名
    public void setName2(String heroName){
        name = heroName;
    }
     
    //通过this访问属性
    public void setName3(String name){
        //name代表的是参数name
        //this.name代表的是属性name
        this.name = name;
    }
     
    public static void main(String[] args) {
        Hero  h =new Hero();
         
        h.setName1("teemo");
        System.out.println(h.name);
         
        h.setName2("garen");
        System.out.println(h.name);    
         
        h.setName3("死歌");
        System.out.println(h.name);    
    }
     
}

  • 通过this调用其他的构造方法
    • 如果要在一个构造方法中,调用另一个构造方法,可以使用this()
public class Hero {
        
    String name; //姓名
        
    float hp; //血量
        
    float armor; //护甲
        
    int moveSpeed; //移动速度
        
    //带一个参数的构造方法
    public Hero(String name){
        System.out.println("一个参数的构造方法");
        this.name = name;
    }
      
    //带两个参数的构造方法
    public Hero(String name,float hp){
        this(name);
        System.out.println("两个参数的构造方法");
        this.hp = hp;
    }
  // 带有四个参数的构造方法
    public Hero(String name, float hp, float armor, int moveSpeed) {
        this(name,hp);
        this.armor = armor;
        this.moveSpeed = moveSpeed;
    }
    public static void main(String[] args) {
        Hero teemo =  new Hero("提莫",383); 
        System.out.println(teemo.name);

        Hero db =  new Hero("死哥",400,27,360);
        System.out.println(db.moveSpeed);         
    }      
}

 

传参

  • 变量有两种类型 基本类型类类型 
  • 参数也是变量,所以传参分为 
    • 基本类型传参 
    • 类类型传参
  • 基本类型传参
    • 在方法内,无法修改方法外的基本类型参数
public class Hero {
        
    String name; //姓名
        
    float hp; //血量
        
    float armor; //护甲
        
    int moveSpeed; //移动速度
     
    public Hero(){
         
    }
     
    //回血
    public void huixue(int xp){
        hp = hp + xp;
        //回血完毕后,血瓶=0
        xp=0;
    }
      
    public Hero(String name,float hp){
        this.name = name;
        this.hp = hp;
    }
 
    public static void main(String[] args) {
        Hero teemo =  new Hero("提莫",383);
        //血瓶,其值是100
        int xueping = 100;
         
        //提莫通过这个血瓶回血
         
        teemo.huixue(xueping);
         
        System.out.println(xueping);         
    }     
}

  • 引用与=
    • 如果一个变量是基本类型
      • 比如 int hp = 50;
      • 我们就直接管hp叫变量
      • =表示赋值的意思。
    • 如果一个变量是类类型
      • 比如 Hero h = new Hero();
        • 我们就管h叫做引用
        • =不再是赋值的意思
        • =表示指向的意思
      • 比如 Hero h = new Hero();
        • 这句话的意思是
        • 引用h,指向一个Hero对象
  • 类类型传参
    • 类类型又叫引用 
    • 第24行的引用 teemo与 第17行的引用hero,是不同的引用 
    • 通过调用garen.attack(teemo, 100); 使得这两个引用都指向了同一个对象 
    • 所以在第18行hero.hp = hero.hp - damage; 就使得该对象的hp值,发生了变化 
    • 因此第25行,打印该对象的Hp值就是变化后的值
public class Hero {
 
    String name; // 姓名
 
    float hp; // 血量
 
    float armor; // 护甲
 
    int moveSpeed; // 移动速度
 
    public Hero(String name, float hp) {
        this.name = name;
        this.hp = hp;
    }
 
    // 攻击一个英雄,并让他掉damage点血
    public void attack(Hero hero, int damage) {
        hero.hp = hero.hp - damage;
    }
 
    public static void main(String[] args) {
        Hero teemo = new Hero("提莫", 383);
        Hero garen = new Hero("盖伦", 616);
        garen.attack(teemo, 100);
        System.out.println(teemo.hp);
    }
 
}

  • 在方法中,使参数引用指向一个新的对象
  • 外面的引用是指向原来的对象?还是新的对象?
public class Hero {
        
    String name; //姓名
        
    float hp; //血量
        
    float armor; //护甲
        
    int moveSpeed; //移动速度
     
    public Hero(){
         
    }
     
    public Hero(String name,float hp){
        this.name = name;
        this.hp = hp;
    }
 
    //复活
    public void revive(Hero h){
        h = new Hero("提莫",383);
    }
 
    public static void main(String[] args) {
        Hero teemo =  new Hero("提莫",383);
         
        //受到400伤害,挂了
        teemo.hp = teemo.hp - 400;
         
        teemo.revive(teemo);
         
        //问题: System.out.println(teemo.hp); 输出多少? 怎么理解?      
    }      
}
  • 在第31行,调用revive的时候,引用h指向 引用teemo所指向的对象 "提莫"
  • 但是teemo引用,还是指向原来的对象
  • 在第22行,引用h指向了新的对象 "新的提莫"
  • 而原来的"提莫" 对象,没有做任何修改,血量依然是负数
  • 最后问 teemo这个引用所指向的对象, 就是"死" 掉的 "提莫" 血量,负数

Java学习笔记:this、传参、包及访问修饰符_第1张图片

包: package 

  • 把比较接近的类,规划在同一个包下
    • Hero,ADHero 规划在一个包,叫做charactor(角色)
    • Item,Weapon规划在另一个包下,叫做 property(道具)

Java学习笔记:this、传参、包及访问修饰符_第2张图片

  • 最开始的地方声明该类所处于的包名
package charactor; //在最开始的地方声明该类所处于的包名
public class Hero {
        
    String name; //姓名
        
    float hp; //血量
        
    float armor; //护甲
        
    int moveSpeed; //移动速度
     
}

  • 使用其他包下的类,必须import
    • 使用同一个包下的其他类直接使用即可 
    • 但是要使用其他包下的类,必须import
package charactor;
 
//Weapon类在其他包里,使用必须进行import
import property.Weapon;
 
public class Hero {
        
    String name; //姓名
        
    float hp; //血量
        
    float armor; //护甲
        
    int moveSpeed; //移动速度
     
    //装备一把武器
    public void equip(Weapon w){
         
    }
        
}

  • 创建一个新的包charactor1,并且让治疗类:Support 声明在这个包下
package charactor1;
import charactor.Hero;
 
public class Support extends Hero {
 
    public void heal() {
        System.out.println("对自己进行治疗");
    }
 
    public void heal(Hero hero) {
        System.out.println("给英雄 " + hero + " 加血");
    }
 
    public void heal(Hero hero, int hp) {
        System.out.println("给英雄 " + hero + " 加了 " + hp + "点血");
    }
}

 

四种访问修饰符

  • 成员变量有四种修饰符
    • private 私有的
    • package/friendly/default 不写
    • protected 受保护的
    • public 公共的
  • 比如public 表示公共的
public String name;
  • 而maxHP 没有修饰符即代表package/friendly/default
float maxHP

  • 类之间的关系
  • 类和类之间的关系有如下几种:
    • 以Hero为例
    • 自身:指的是Hero自己
    • 同包子类:ADHero这个类是Hero的子类,并且和Hero处于同一个包下
    • 不同包子类:Support这个类是Hero的子类,但是在另一个包下
    • 同包类: GiantDragon 这个类和Hero是同一个包,但是彼此没有继承关系
    • 其他类:Item这个类,在不同包也没有继承关系的类

Java学习笔记:this、传参、包及访问修饰符_第3张图片


  • private 私有的
    • 使用private修饰属性
      • 自身:是可以访问的
      • 同包子类:不能继承
      • 不同包子类:不能继承
      • 同包类:不能访问
      • 其他包类:不能访问
package charactor;
 
import property.Weapon;
 
public class Hero {
 
    //属性id是private的,只有Hero自己可以访问
    //子类不能继承
    //其他类也不能访问
    private int id;
     
    String name;
 
    float hp;
 
    float armor;
 
    int moveSpeed;
 
    public void equip(Weapon w) {
 
    }
 
}

  • package/friendly/default 不写
    • 没有修饰符即代表package/friendly/default 
    • package限定在这个包的范围内
      • 自己可以访问
      • 同包子类可以继承
      • 不同包子类不能继承 
      • 同包类可以访问
      • 不同包类不能访问
  • float maxHP; 血量上限
package charactor;
 
import property.Weapon;
 
public class Hero {
    private int id;
 
    String name;
 
    // 无修饰符的属性 hp
    // 自己可以访问
 
    // 同包子类可以继承
    // 不同包子类不能继承
 
    // 同包类可以访问
    // 不同包类不能访问
    float hp;
 
    float armor;
 
    int moveSpeed;
 
    public void equip(Weapon w) {
 
    }
 
}

  • protected 受保护的
    • 受保护的修饰符
      • 自己可以访问
      • 同包子类可以继承
      • 不同包子类可以继承
      •  同包类可以访问
      • 不同包类不能访问
  • protected float hp; 血量
package charactor;
 
import property.Weapon;
 
public class Hero {
    private int id;
 
    String name;
 
    // protected饰符的属性 hp
    // 自己可以访问
 
    // 同包子类可以继承
    // 不同包子类可以继承
 
    // 同包类可以访问
    // 不同包类不能访问
    protected float hp;
 
    float armor;
 
    int moveSpeed;
 
    public void equip(Weapon w) {
 
    }
 
}

  • public 公共的
    • 公共的修饰符 
    • public String name; 姓名 
    • 任何地方,都可以访问
      • 自己可以访问
      • 同包子类可以继承
      • 不同包子类可以继承
      • 同包类可以访问
      • 不同包类可以访问
package charactor;
 
import property.Weapon;
 
public class Hero {
    private int id;
 
    // public的属性 name
    // 自己可以访问
 
    // 同包子类可以继承
    // 不同包子类可以继承
 
    // 同包类可以访问
    // 不同包类可以访问
    public String name;
 
    protected float hp;
 
    float armor;
 
    int moveSpeed;
 
    public void equip(Weapon w) {
 
    }
 
}

  • 那么什么情况该用什么修饰符呢?
    • 1. 属性通常使用private封装起来
    • 2. 方法一般使用public用于被调用
    • 3. 会被子类继承的方法,通常使用protected
    • 4. package用的不多
  • 作用范围最小原则
    • 简单说,能用private就用private,不行就放大一级,用package,再不行就用protected,最后用public。 这样就能把数据尽量的封装起来,没有必要露出来的,就不用露出来了

你可能感兴趣的:(Java学习之路,java)