类和对象10.25
引用
引用的概念,变量的类型是 类类型,不是基本类型,那么该变量又叫引用
new Hero();
// 代表创建了一个Hero对象,但仅是创建而已,没有办法进行访问
// 为了访问该对象,会使用引用来代表该对象
Hero h = new Hero();
// h变量是Hero类型,又叫引用
// =是指h这个引用代表右边创建的对象,“代表”在面向对象里,又叫“指向”
public class Hero{
String name;
float hp;
float armor; // 护甲
int moveSpeed; // 移动速度
public static void main(String[] args){
new Hero(); // 创建一个对象
Hero h = new Hero(); // 使用一个引用来指定这个对象
}
}
//多个引用,一个对象
//引用有多个,但对象只有一个,底层逻辑图如下方所示
public class Hero {
String name;
float hp;
float armor;
int moveSpeed;
public static void main(String[] args){
Hero h1 = new Hero(); //使用一个引用来指向这个对象
Hero h2 = h1; //h2 指向h1所指向的对象
Hero h3 = h1;
Hero h4 = h1; //多个引用,都指向h1,h1相当于原件,其它的相当于复印件
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DcVOMyNs-1635256759440)(X:\Users\Administrator.DESKTOP-HQEE7OG\AppData\Roaming\Typora\typora-user-images\image-20211025164301625.png)]
/*
一个引用,多个对象
*/
package charactor;
public class Hero {
public String name;
protected float hp;
public static void main(String[] args){
Hero garen = new Hero(); //引用garen指向新创建的对象(对象1)
garen = new Hero(); //同一个引用garen指向新创建的对象(对象2)
//这个时候,对象1,就没有任何引用的指向了,没有任何手段控制和访问该对象,那么该对象就变得没有意义
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nFmWLizW-1635256759443)(X:\Users\Administrator.DESKTOP-HQEE7OG\AppData\Roaming\Typora\typora-user-images\image-20211025164852894.png)]
继承
说明:如“王者农药”中,武器是物品的一种,也是有名称和价格的,在设计类的时候,可以让武器继承物品,从而继承名称和价格属性
物品类Item
//物品类ltem有属性name,price
public class Item{
String name;
int price;
}
武器类Weapon(不继承)
//武器类:Weapon不继承的写法
//独立设计name和price属性
//同时多了一个属性damage攻击力
public class Weapon{
String name;
int price;
int damage;
}
武器类Weapon(继承类Item)
// 这一次Weapon继承Item
// 虽然Weapon自己没有设计name和price,但是通过继承Item类,也具备了name和price属性
public class Weapon extends Item{
int damage;
public static void main(String[] args){
Weapon infinityEdge = new Weapon();
infinityEdge.damage = 65; //damage属性在类Weapon中新设计的
infinityEdge.name = "无尽之刃";//name属性,是从Item中继承来的,就不需要重复设计了
infinityEdge.price = 3600;
}
}
练习
package bese;
/*
设计一个类Armor护甲
继承Item类,并且额外提供一个属性ac: 护甲等级 int类型
实例化出两件护甲
名称 价格 护甲等级
布甲 300 15
锁子甲 500 40
*/
public class Weapon extends Item {
int ac;
public static void main(String[] args) {
Weapon bujia = new Weapon();
Weapon suozijia = new Weapon();
bujia.ac = 15;
suozijia.ac = 40;
bujia.name = "布甲";
suozijia.name = "锁子甲";
bujia.price = 300;
suozijia.price = 500;
System.out.println("名称"+" "+ "价格"+" "+"护甲等级");
System.out.println(bujia.name+" "+ bujia.price+" "+bujia.ac);
System.out.println(suozijia.name+ " "+suozijia.price+" "+suozijia.ac);
}
}
方法重载
说明:方法重载是指方法名一样,但参数类型不一样
-
attack方法的重载
-
// 王者农药为例,英雄也分不同类型,如物理攻击型ADHero public void attack() public void attack(Hero h1) //为ADHero提供三种方法 public void attack(Hero h1,Hero h2) //方法名是一样的,但是参数不一样 //在调用方法attack时,会根据传递的类型以及数量,自动调用对应的方法
-
package bese; public class Hero { String name; float hp; public void attack(Hero h){ System.out.println(name + "攻击了" + h.name); } public void attack(Hero h1,Hero h2){ System.out.println(name +"同时攻击了"+h1.name+"和"+h2.name ); } public static void main(String[] args) { Hero gareen = new Hero(); gareen.name = "盖伦"; Hero teemo = new Hero(); teemo.name = "提莫"; Hero db = new Hero(); db.name = "死歌"; gareen.attack(teemo,db); } }
可变数量的参数
呈上,如果要同时攻击多个英雄,就会设计很多的方法
public void attack(Hero h1)
public void attack(Hero h1,Hero h2)
public void attack(Hero h1,Hero h2,Hero h3)
//这样的操作就很繁琐
//可以采用课变数量的参数
public void attack(Hero ...heros)
//只需要设计这样一个方法,就可以代表上述的所有方法了
//该方法中,使用操作数组的方式处理参数heros就可以了
package bese;
public class Hero {
String name;
float hp;
public void attack(Hero h){
System.out.println(name + "攻击了" + h.name);
}
public void attack(Hero ...heroes){ //可变参数方法,该方式相
// 当于public void attack(Hero[] heros){} 数组类型
for (Hero hero : heroes){ //for循环,数组的方式处理
System.out.println(name + "同时攻击了"+ hero.name);
}
}
public static void main(String[] args) {
Hero gareen = new Hero();
gareen.name = "盖伦";
Hero teemo = new Hero();
teemo.name = "提莫";
Hero db = new Hero();
db.name = "死歌";
Hero annie = new Hero();
annie.name = "火女";
gareen.attack(teemo);
teemo.attack(gareen,db,annie); //这里如果使用的是数组的方法,需要调用参数
//使用的是可变的方法,就不需要调用,直接使用
}
}
构造方法
说明:通过一个类创建的一个对象,这个过程叫做实例化,实例化是通过调用构造方法(有叫构造器)进行实现
package bese;
/*
什么事构造方法?
*/
public class Hero {
String name;
float hp;
float armor;
int moveSpeed;
/*
方法名和类名一样(包括大小写)
没有返回的类型
*/
public Hero(){
System.out.println("实例化一个对象的时候,必然调用构造方法");
}
public static void main(String[] args) {
Hero h = new Hero(); //实例化一个对象的时候,必然调用构造方法
}
}
隐藏的构造方法
package bese;
public class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
/*这里无参数的构造方法,不写
就会默认提供一个午无参的构造方法
public Hero(){
System.out.println("调用Hero的的构造方法");
}
*/
public static void main(String[] args) {
Hero garen = new Hero();
garen.name = "盖伦";
garen.hp = 616.28f;
garen.armor = 27.536f;
garen.moveSpeed = 350;
Hero teemo = new Hero();
teemo.name = "提莫";
teemo.hp = 383f;
teemo.armor = 14f;
teemo.moveSpeed = 330;
}
}
如果提供了一个有参的构造方法
//提供了一个有参的构造方法,同时有没有显示的提供一个无参的构造方法,那么默认的无参的构造方法就没有了
public class Hero{
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
/*有参的构造方法
默认的无参构造方法就失效了
*/
public static void main(String[] args){
Hero garen = new Hero("盖伦");
Hero teemo = new Hero();//这是无参的方法,这里就没有了
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-joa6uBK8-1635256759446)(X:\Users\Administrator.DESKTOP-HQEE7OG\AppData\Roaming\Typora\typora-user-images\image-20211026171711183.png)]
构造方法的重载
//和普通的构造方法是一样的,构造方法同样也是可以重载的
package bese;
public class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
//带一个参数的构造方法
public Hero(String heroname){
name = heroname;
}
//带两个参数的构造方法
public Hero(String heroname,float herohp){
name = heroname;
hp = herohp;
}
public static void main(String[] args) {
Hero garen = new Hero("盖伦");
Hero teemo = new Hero("提莫",383);
}
}
练习-构造方法
/*
为Hero设计3个参数的构造方法
这3个参数分别是
String heroNmae
float heroArmor
int heroMoveSpeed
*/
package bese;
public class Hero {
String name; //姓名
float armor; //护甲
int moveSpeed; //移动速度
public Hero(String heroname,float heroarmor,int heroMoveSpeed){ //三个参数的构造方法
name = heroname;
armor = heroarmor;
moveSpeed = heroMoveSpeed;
}
public static void main(String[] args) {
Hero h = new Hero("Teemo",531,355);
//调用三个参数的构造方法
System.out.println(h.name);
System.out.println(h.armor);
System.out.println(h.moveSpeed);
}
}
this
说明:this代表当前对象。相当于“我” 的意思,如小红说“我吃了个大西瓜“,”我“代表小红
public class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
//打印内存中的虚拟地址
public void showAddressInMemory(){ //show展示 Address地址 Memory记忆 内存
System.out.println("打印this看到的虚拟地址:"+ this);
}
public static void main(String[] args) {
Hero garen = new Hero();
garen.name = "盖伦";
//直接打印对象,会显示对象在内存中的虚拟地址
//格式:bese.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关键字访问对象的属性 package bese; 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() package bese; 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 static void main(String[] args) { Hero teemo = new Hero("提莫",381); System.out.println(teemo.name); } }
-
练习-构造方法this
-
/*参考练习-构造方法 设计一个构造方法,但是参数名称不太一样,分别是 String name float hp float armor int moveSpeed 不仅如此,在这个构造方法中,调用这个构造方法 public Hero(String name,float hp) */ package bese; //带不同参数的构造方法之间的相互调用 public class Hero { /*参考练习-构造方法 设计一个构造方法,但是参数名称不太一样,分别是 String name float hp float armor int moveSpeed 不仅如此,在这个构造方法中,调用这个构造方法 public Hero(String name,float hp) */ String name; //姓名 float hp; //血量 float armor; //护甲 int moveSpeed; //移动速度 public Hero(){ System.out.println("无参构造方法"); } public Hero(String name){ this.name = name; System.out.println("一个参数的构造方法"); } public Hero(String name,float hp){ this(name); //会先调用带一个参数的构造方法 this.hp = hp; System.out.println("两个参数的构造方法"); } public Hero(String name,float hp,float armor,int moveSpeed){ this(name,hp); //会先调用带两个参数的构造方法 this.armor = armor; this.moveSpeed = moveSpeed; System.out.println("带四个参数的构造方法"); } public void showAddressInMemory(){ System.out.println("打印this看到的虚拟地址:"+ this); } public static void main(String[] args) { Hero teemo = new Hero("提莫",383); //调用两个参数的方法 System.out.println(teemo.name); Hero ds = new Hero("死歌",400,24,365); System.out.println(ds.moveSpeed); System.out.println("打印对象看到的虚拟地址:"+ teemo); teemo.showAddressInMemory(); } }