- 接口
接口类似于一种约定,假设约定一些英雄是物理系英雄,那么其一定可以进行物理攻击。
物理攻击接口 物理攻击英雄
//定义物理攻击接口 package charactor; public interface AD{ public void physicAttack(); } //定义物理攻击英雄继承该接口 package charactor; public class ADHero extends Hero implements AD{ @Override public void physicAttack(){ System.out.println("进行物理攻击"); } }
魔法攻击接口 魔法攻击英雄
//定义魔法攻击接口 package charactor; public interface AP{ public void magicAttack(); } //定义魔法攻击英雄继承该接口 package charactor; public class APHero extends Hero implements AP{ public void magicAttack(){ @Override System.out.println("进行魔法攻击"); }; }
物理魔法混合型英雄
package charactor; public class ADAPHero extends Hero implements AP,AD{ @Override public void magicAttack() { System.out.println("进行魔法攻击"); } @Override public void physicAttack() { System.out.println("进行物理攻击"); } }
- 对象转型(对象类型和引用类型不一致的问题)
向上转型(子类转父类)
向上转型一定可以成功,口诀:“把右边当左边来用,看能不能说得通” ,如:把苹果手机当成手机,肯定说的通 Phone p = new Iphone();
向下转型(父类转子类)
有时候行,有时候不行,所以需要强制类型转换
可以转换:需要父类引用变量指向的对象为要转换目标子类对应类型的对象
Hero h =new Hero(); ADHero ad = new ADHero(); h = ad; ad = (ADHero) h;
不可以转换 :父类引用变量类型指向的对象和要转换目标子类对应的类型不一致
Hero h =new Hero(); ADHero ad = new ADHero(); Support s =new Support(); h = s; ad = (ADHero)h;
没有继承关系的两个类相互转换一定会失败
接口类可以看作其实现类的父类,因此其转换关系完全满足上述规则。
instanceof 判定一个引用所指向的对象, 如:h instanceof Hero h1 insatnceof ADHero
- 重写 override(子类继承父类后,重复提供该方法,就叫方法的重写)
- 多态
操作符多态: +可以作为算数加运算,又可以连接字符串
类多态: 父类引用指向子类对象
条件:1. 父类(接口)指向子类对象 2.调用的方法有重写
package charactor; import property.Item; import property.LifePotion; import property.MagicPotion; public class Hero { public String name; protected float hp; public void useItem(Item i){ i.effect(); } public static void main(String[] args) { Hero garen = new Hero(); garen.name = "盖伦"; LifePotion lp =new LifePotion(); MagicPotion mp =new MagicPotion(); garen.useItem(lp); garen.useItem(mp); } }
- 隐藏
隐藏是子类覆盖父类的类方法,而重写是子类覆盖父类的对象方法
- super 关键字
super作用:调用父类构造方法;调用父类属性;调用父类方法。
- Object类 (所有类的父类)
Object提供的相关方法如下所示:
toString() :返回当前对象的字符串表达,通过System.out.println 打印对象就是打印该对象的toString()返回值
finalize() :当一个对象没有任何一个引用指向时,会被调用(垃圾回收)
equals() :判断两个对象内容是否相同
== :不是Object提供的方法,其主要判断两个引用是否指向同一个对象
hashCode(): 返回一个对象的哈希值
wait() notify() notifyAll() :线程同步相关方法
getClass(): 返回一个对象的类对象 反射相关
- final
修饰类:当final修饰类时,表示该类不能被继承
修饰方法:不能被重写
修饰基本类型变量: 表示该变量只有一次赋值机会
修饰引用:表示该引用只有一次指向对象的机会
常量:可以公开,直接访问,不会变化的值 such as : public
static
final
int
itemTotalNumber =
6
;
- 抽象类
当一个类中存在抽象方法(abstract修饰,该方法没有实现体),那么该类必须被声明为抽象类(同样用abstract修饰)。
一旦一个类被声明为抽象类,那么就不能被实例化
抽象类和接口的区别:
1. 子类只能继承一个抽象类,不能继承多个;子类可以实现多个接口
2. 抽象类可以定义 public,protected,package,private 静态和非静态 final和非final 属性 接口中的属性是能是 public 静态的 final
抽象类和接口都可以有实体方法。 接口中的实体方法,叫做默认方法
默认方法为jdk1.8提供的新特性:
package charactor; public interface Mortal { public void die(); default public void revive() { System.out.println("本英雄复活了"); } }
通过默认方法这种手段,就能够很好的扩展新的类,并且做到不影响原来的类
- 内部类:
非内部静态类: new 外部类().new 内部类() 可以直接访问外部类的private实例属性
内部静态类: new 外部类.静态内部类() 在静态内部类里面不可以访问外部类的实例属性和方法,除了可以访问外部类的私有静态成员外,静态内部类和普通类没什么大的区别
匿名类: 声明一个类的同时实例化它,使代码更加简洁精练。 通常情况下,要使用一个接口或者抽象类,都必须创建一个子类。 有时候,为了快速使用,直接实例化一个抽象类,并“当场”实现其抽象方法。既然实现了抽象方法,那么就是一个新的类,只是这个类,没有命名,这就是匿名类。
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); } }
本地类:
本地类可以理解为有名字的匿名类,内部类与匿名类不一样的是,内部类必须声明在成员的位置,即与属性和方法平等的位置地类和匿名类一样,直接声明在代码块里面,可以是主方法,for循环里等等地方。
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(); } }
在匿名类中使用外部的局部变量时,必须将外部变量声明为final, 原因如下:
匿名类调用外部的局部变量时,相当于将外部局部变量作为一个构造器参数传给了匿名类 Java中只有值传递,也就是说,匿名类得到的是外部局部变量的副本 这个副本的生效范围只在匿名类中,无论怎么更改都不会对外部局部变量造成影响 为了避免开发者混淆,Java干脆不让修改用到的外部局部变量了 这样处理也导致了不方便,外部类后续也无法修改这个局部变量了