java面向对象2(学习笔记HOW2J)

  • 接口

  接口类似于一种约定,假设约定一些英雄是物理系英雄,那么其一定可以进行物理攻击。

  物理攻击接口        物理攻击英雄

//定义物理攻击接口
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干脆不让修改用到的外部局部变量了 这样处理也导致了不方便,外部类后续也无法修改这个局部变量了



    

 

 

 

 

 

 

  

posted @ 2020-02-12 17:30  semieZX  阅读(223)  评论(0编辑  收藏  举报