equals() 用于判断两个对象的内容是否相同。
当两个英雄的 hp 相同的时候,我们就认为这两个英雄相同。
public class Hero {
public String name;
protected float hp;
public boolean equals(Object o){
if(o instanceof Hero){
Hero h = (Hero) o;
return this.hp == h.hp;
}
return false;
}
public static void main(String[] args) {
Hero h1= new Hero();
h1.hp = 300;
Hero h2= new Hero();
h2.hp = 400;
Hero h3= new Hero();
h3.hp = 300;
System.out.println(h1.equals(h2)); //false
System.out.println(h1.equals(h3)); //true
}
}
这不是 Object 的方法,但是用于判断两个对象是否相同。
更准确的说,用于判断两个引用,是否指向同一个对象。
hashCode 方法返回一个对象的哈希值。默认情况下,Object 类的 hashCore() 方法根据该对象的地址来计算。
但很多类都重写了 Object 类的 hashCode() 方法,不再根据地址来计算其 hashCode() 方法值。
public class Hero {
public String name;
protected float hp;
public boolean equals(Object o){
if(o instanceof Hero){
Hero h = (Hero) o;
return this.hp == h.hp;
}
return false;
}
public static void main(String[] args) {
Hero h1= new Hero();
h1.hp = 300;
Hero h2= new Hero();
h2.hp = 400;
Hero h3= new Hero();
h3.hp = 300;
Hero h4 = h1;
System.out.println(h1==h2); //false
System.out.println(h1==h3); //false
System.out.println(h1==h4); //true
System.out.println("h1.hashCode:"+h1.hashCode()); //h1.hashCode:2018699554
System.out.println("h2.hashCode:"+h2.hashCode()); //h2.hashCode:1311053135
System.out.println("h3.hashCode:"+h3.hashCode()); //h3.hashCode:118352462
System.out.println("h4.hashCode:"+h4.hashCode()); //h4.hashCode:2018699554
}
}
final 修饰类,方法,基本类型变量,引用的时候分别有不同的意思。
当 Hero 被修饰成 final 的时候,表示 Hero 不能够被继承。
Hero 的useItem 方法被修饰成 final,那么giant方法在 ADHero 中,不能够被重写。
final 修饰基本变量,表示该变量只有一次赋值机会。
表示该引用只有 1 次指向对象的机会。
在类中声明一个方法,这个方法没有实现体,只是一个“空”方法。
这样的方法就叫抽象方法,使用修饰符“abstract”
当一个类有抽象方法的时候,该类必须被声明为抽象类。
为 Hero 增加一个抽象方法 attack,并且把 Hero 声明为 abstract 的。
APHero,ADHero,ADAPHero 是 Hero 的子类,继承了 Hero 的属性和方法。
但各自的共计手段是不一样的,所有继承 Hero 类后,这些子类就必须提供不一样的 attack 方法实现。
Hero 类可以在不提供抽象方法的前提下,声明为抽象类。
一旦一个类被声明为抽象类,就不能被直接实例化。
package charactor;
public abstract class Hero {
String name;
float hp;
float armor;
int moveSpeed;
public static void main(String[] args) {
//虽然没有抽象方法,但是一旦被声明为了抽象类,就不能够直接被实例化
Hero h= new Hero(); //error
}
}
区别一:
区别二:
内部类分为四种:
非静态内部类 BattleScore “战斗成绩”
非静态内部类可以直接在一个类里面定义。比如:
public class Hero {
private String name; // 姓名
float hp; // 血量
float armor; // 护甲
int moveSpeed; // 移动速度
// 非静态内部类,只有一个外部类对象存在的时候,才有意义
// 战斗成绩只有在一个英雄对象存在的时候才有意义
class BattleScore {
int kill;
int die;
int assit;
public void legendary() {
if (kill >= 8)
System.out.println(name + "超神!");
else
System.out.println(name + "尚未超神!");
}
}
public static void main(String[] args) {
Hero garen = new Hero();
garen.name = "盖伦";
// 实例化内部类
// BattleScore对象只有在一个英雄对象存在的时候才有意义
// 所以其实例化必须建立在一个外部类对象的基础之上
BattleScore score = garen.new BattleScore();
score.kill = 9;
score.legendary();
}
}
一个类里面声明一个静态内部类
public class Hero {
public String name;
protected float hp;
private static void battleWin(){
System.out.println("battle win");
}
//敌方的水晶
static class EnemyCrystal{
int hp=5000;
//如果水晶的血量为0,则宣布胜利
public void checkIfVictory(){
if(hp==0){
Hero.battleWin();
//静态内部类不能直接访问外部类的对象属性
System.out.println(name + " win this game"); //error
}
}
}
public static void main(String[] args) {
//实例化静态内部类
Hero.EnemyCrystal crystal = new Hero.EnemyCrystal();
crystal.checkIfVictory();
}
}
匿名类指的是在声明一个类的同时实例化它,使代码更加简洁精炼。
这样的类,叫做匿名类。
public abstract class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
public abstract void attack();
public static void main(String[] args) {
ADHero adh = new ADHero();
//通过打印adh,可以看到adh这个对象 属于ADHero类
adh.attack();
System.out.println(adh);
Hero h = new Hero() {
//当场实现attack方法
public void attack() {
System.out.println("新的进攻手段");
}
};
h.attack();
//通多打印h,可以看到h这个对象属于Hero$1这么一个系统自动分配的类名
System.out.println(h);
}
}
public abstract class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
public abstract void attack();
public static void main(String[] args) {
//与匿名类的区别在于,本地类有了自定义的类名
class SomeHero extends Hero{
public void attack() {
System.out.println( name+ " 新的进攻手段");
}
}
SomeHero h =new SomeHero();
h.name ="地卜师";
h.attack();
}
}