- 接口
1.定义
类(被声明为interface),方法均为空方法(JDK8新特性新增默认方法),由其他类(该类可以实现多个接口)实现。
注:接口就像是一种约定,我们约定某些英雄是物理系英雄,那么他们就一定能够进行物理攻击。
package charactor;
//物理攻击接口
public interface AD {
//物理伤害
public void physicAttack();//抽象方法,abstract可以省略
}
package charactor;
//魔法攻击接口
public interface AP {
//魔法伤害
public void magicAttack();
}
package charactor;
//子类ADHero继承父类Hero实现接口AD
public class ADAPHero extends Hero implements AD,AP{
public void physicAttack() {
System.out.println("进行物理攻击");
}
public void magicAttack() {
System.out.println("进行魔法攻击");
}
}
class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed; //移动速度
}
2.默认方法
package charactor;
public interface AD {
public void physicAttack();
default public void attack() {
System.out.println("物理攻击");
}
}
public class ADHero extends Hero implements AD{
public void physicAttack() {
System.out.println("进行物理攻击");
}
public static void main(String[] args) {
ADHero ad=new ADHero();
ad.attack();//物理攻击
}
}
- 重写
定义:子类继承父类,在继承后,重复提供该方法。(又叫覆盖 override)
package property;
//父类Item
public class Item {
String name;
int price;
public void buy(){
System.out.println("购买");
}
public void effect() {
System.out.println("物品使用后,可以有效果");
}
}
package property;
//子类LifePotion继承Item,同时也提供了方法effect
public class LifePotion extends Item{
public void effect(){
System.out.println("血瓶使用后,可以回血");
}
}
- 封装
定义:修改属性的可见性来限制对属性(限制为private)的访问,任何要访问类中私有成员变量的类都要通过这些getter和setter方法。
public class Person{
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
- 抽象类
1.定义:抽象类(修饰符“abstract" )有抽象方法时,子类继承父类必须提供该方法实现,且子类只能继承一个抽象类。
package charactor;
public abstract class Hero {
String name;
float hp;
float armor;
int moveSpeed;
public static void main(String[] args) {
}
// 抽象方法attack
// Hero的子类会被要求实现attack方法
public abstract void attack();
}
package charactor;
public class ADHero extends Hero implements AD {
public void physicAttack() {
System.out.println("进行物理攻击");
}
@Override
public void attack() {
physicAttack();
}
}
2.抽象类可以没有抽象方法
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();//报错
}
}
3.抽象类和接口的区别
区别1:
子类只能继承一个抽象类,不能继承多个
子类可以实现多个接口
区别2:
抽象类可以定义
public,protected,package,private
静态和非静态属性
final和非final属性
但是接口中声明的属性,只能是
publil 静态 final的(即必须定义为常量)
即便没有显式的声明
package charactor;
public interface AP {
public static final int resistPhysic = 100;
//resistMagic即便没有显式的声明为 public static final
//但依然默认为public static final
int resistMagic = 0;
public void magicAttack();
}
- 多态
1.定义:子类继承父类,有方法重写,父类引用指向子类对象。
接口的多态:子接口继承父接口,类实现子接口,且子接口引用指向该类对象。
package property;
public class Item {
String name;
int price;
public void buy(){
System.out.println("购买");
}
public void effect() {
System.out.println("物品使用后,可以有效果 ");
}
public static void main(String[] args) {
Item i1= new LifePotion();
System.out.print("i1 是Item类型,执行effect打印:");
i1.effect();
}
}
package property;
public class LifePotion extends Item {
public void effect(){
System.out.println("血瓶使用后,可以回血");
}
}
接口的多态(之后集合框架会讲)
- 隐藏
定义:与重写类似,方法的重写是子类覆盖父类的对象方法 。
隐藏,就是子类覆盖父类的类方法。
package charactor;
public class Hero {
public String name;
protected float hp;
//类方法,静态方法
//通过类就可以直接调用
public static void battleWin(){
System.out.println("hero battle win");
}
}
package charactor;
public class ADHero extends Hero implements AD{
@Override
public void physicAttack() {
System.out.println("进行物理攻击");
}
//隐藏父类的battleWin方法
public static void battleWin(){
System.out.println("ad hero battle win");
}
public static void main(String[] args) {
Hero.battleWin();
ADHero.battleWin();
}
}
若是Hero h =new ADHero();h.battleWin();会调用父类的方法(尽量不要用)。
注:对于静态方法(即类方法),正确的调用方式是直接通过类名来调用的。
- super关键字
1.实例化子类,父类的构造方法(且是父类构造方法先调用 )一定会被调用
子类构造方法会默认调用父类(且先调用 )的无参构造方法
package charactor;
public class ADHero extends Hero implements AD{
@Override
public void physicAttack() {
System.out.println("进行物理攻击");
}
public ADHero(){
System.out.println("AD Hero的构造方法");
}
public static void main(String[] args) {
new ADHero();
}
}
class Hero {
public Hero(){
System.out.println("Hero的构造方法 ");
}
}
2.子类显式调用父类带参构造方法
package charactor;
public class ADHero extends Hero implements AD{
@Override
public void physicAttack() {
System.out.println("进行物理攻击");
}
public ADHero(String name){
super(name);//调用父类的有参构造方法
System.out.println("AD Hero的构造方法");
}
public static void main(String[] args) {
new ADHero("德莱文");
}
}
class Hero {
String name; //姓名
public Hero(){
System.out.println("Hero的构造方法 ");
}
public Hero(String name){
System.out.println("Hero的有一个参数的构造方法 ");
this.name = name;
}
}
- 内部类:
四种:非静态内部类 静态内部类 匿名类 本地类
1.非静态内部类
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 的时候,必须建立在一个存在的英雄的基础上
语法: 实例化对象.new 内部类()*/
BattleScore score=garen.new BattleScore();
score.kill=9;
score.legendary();//作为Hero的非静态内部类,是可以直接访问外部类的private实例属性name的
}
}
2.静态内部类
public class Hero {
public String name;
protected float hp;
private static void battleWin(){
System.out.println("battle win");
}
//敌方水晶//静态内部类
static class EnemyCrystal{
int hp=0;
//如果水晶的血量为0,则宣布胜利
public void checkIfVictory(){
if(hp==0){
Hero.battleWin();
//静态内部类不能直接访问外部类的对象属性,如System.out.println(name+ " win this game");会报错
System.out.println( " win this game");
}
}
}
public static void main(String[] args) {
//实例化静态内部类
Hero.EnemyCrystal crystal=new Hero.EnemyCrystal();
crystal.checkIfVictory();
}
}
实例化对象区别
非静态内部类
Hero garen = new Hero(); BattleScore score= garen.new BattleScore();
静态内部类
Hero.EnemyCrystal crystal=new Hero.EnemyCrystal();
3.匿名类
一旦被声明为了抽象类,就不能够直接被实例化(借助匿名类可以直接实现方法)
public abstract class Hero {
private 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);
}
}
注:有的时候,为了快速使用,直接实例化一个抽象类,并“当场”实现其抽象方法。
既然实现了抽象方法,那么就是一个新的类,只是这个类,没有命名。
这样的类,叫做匿名类
补充:在匿名类中使用外部的局部变量
在jdk8中,已经不需要强制修饰成final了,如果没有写final,不会报错,因为编译器偷偷的帮你加上了看不见的final。
package charactor;
public abstract class Hero {
public abstract void attack();
public static void main(String[] args) {
//在匿名类中使用外部的局部变量,外部的局部变量必须修饰为final(jdk8之前)
final int damage = 5;
Hero h = new Hero(){
public void attack() {
System.out.printf("新的进攻手段,造成%d点伤害",damage );
}
};
}
}
为什么要酱紫?不告诉你~~~
- 本地类
package charactor;
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();
}
}