2020.4.22课堂笔记(继承、多态、抽象类、抽象方法)

在继承的情况下,子类的方法满足以下条件:
1、方法名相同
2、参数列表相同
3、返回值类型相同,或者是父类返回值类型的子类
4、访问修饰符的权限不能小于父类方法
5、抛出的异常不能大于父类(严于)

多态

抽象类abstract关键字修饰类
抽象类不能被实例化(不能创建对象)含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写

抽象方法:
抽象方法必须在抽象类中
抽象方法没有结构体
子类继承抽象类的时候,必须实现父类的抽象方法,除非这个子类也是抽象类

TestFinal.java
public class TestFinal{
public static void main(String[] args){
T t=new T;
//t.i=8;
}
}
class T{
final int i=8;
public void m(final Cat cat){//不能让这个引用指向其他的猫
j=9;//报错不能指定最终参数j(final int j 的时候)
}
}
public final void m(){
//
}
Final关键字:
public final class String /public final class Math /public final class Boolean
不能被继承,重写方法
final的变量值不能被改变(成员变量、局部变量)
final的方法不能被重写
final的类不能被继承

java中是单继承、但是生活中存在多继承的现象,不可以这么写就是使用接口
接口:本质上讲,接口是一种特殊的抽象类,在这个抽象类里面,所有的方法都是抽象方法,
所有的成员变量都必须是public static final的,只包含常量和方法的定义,而没有变量和方法的实现。
public interface Runner{
public static final int id=1;
public void start();//所有的方法不用写abstract实际都是abstract的
}
一个类可以实现多个接口
接口中声明的属性默认是public static final也只能是public static final的
一个接口里面的方法只能是public的抽象方法
接口和实现类之间存在多态性 只能看到实现类中自己的方法
Singer s=new Student(); //把student当作singer来看,每一个接口暴露了对象的一部分方法,使用什么样的接口,只能访问这个接口对应的方法
s.sing();
只要实现了这个接口的任意一个类的对象都可以往里面传,new这个对象出来就可以往里面传,
重写了我sing的方法,我实际调用的就是重写的方法,接口本质上仍然是一个类,帮助我们实现多重继承
f(Singer s){
s.sing();
}
第三章总结:
内存分析贯穿始终
对象和类的概念
类是具有同样特征的同一类事物的抽象
对象是这类事物的特殊的实例
类和对象直接的关系:关联、继承、聚合(聚集、组合)、多态、实现
面向对象设计思想:和面向过程不一样,这个问题里有哪些类哪些对象,类里面有哪些属性哪些方法,类和类之间有什么关系,有没有继承、多态的关系
Class、new关键字,引用的概念:一小块内存指向一大块内存,new一般和构造方法一起使用,构造一个新对象的时候调用的方法,和类同名,没有返回值,void都不可以写。
方法的重载,方法名字一样,参数列表不同(参数的类型不一样或者参数的个数不一样)
this关键字:当前对象,你现在在调用哪个方法,this指的就是谁,内存里new出一个对象来,有一个自己的引用指向自身
static的成员变量是属于所有类的,一般分配在data区域里面,属于这个类的所有对象,属于整个类,不需要new这个对象就可以去访问它。非static的必须去new一个对象出来才可以去访问它的值,static不需要,只要用类名.就可以访问它的值,或者来访问这个方法。
package解决类重名的问题,约定俗成、公司域名倒过来
访问控制:private 修饰成员变量,只有自己能访问,出了类没有人能访问它
default同一个包里面其他类可以访问
protected它的子类可以访问
public所有类都能访问
default和public还可以修饰class
所有的关键字都可以修饰内部类,
extends继承,一个类从另外一个类继承,封装了这样一种语义,XXX是一种XXX,只要说通了,它们之间是一种继承关系。继承下来相当于拥有了那个类所有的成员变量,所有的方法,包括private的,但是对于private的成员变量,拥有了所有权但是没有使用权
overwrite:方法的重写
父类实现一方法不满意,重写。重写的时候有一个best practise最佳的实践
final的变量不能改变值,final的方法不能被重写,final的class不能被继承
Object
toString封装了一个对象在一个字符串上的表现,可以重写它,写一个字符串,来表现它
upcasting父类引用指向子类对象/接口的引用指向实现的对象,向上转型
downcasting向下转型
多态:要有继承、要有重写、父类引用指向子类对象
多态也叫动态绑定dynamic binding 迟绑定 late binding:new的是哪个类,我就找那个类对象的方法,这叫动态绑定
abstract class有抽象方法的类叫做抽象类,抽象方法只有定义,没有实现
interface接口
特殊的抽象类,所有的方法都是抽象方法,而且都是public的,所有的成员变量都是public static final的
接口和接口之间可以互相继承,类和类之间可以互相继承,类和接口之间只能实现implements
一个类可以实现多个接口,多个类可以实现一个接口,内存里可以看见这个对象的一部分方法,这就是接口。

Cat:

package cn.kgc.kb09;

/**
 * @Author: ChaoKeAiMuZhi
 * @Date: 2020/7/22 16:13
 * @Description:
 **/
public class Cat extends Pet {
     

    @Override
    public void toHospital() {
     
        if(getHealth()<50){
     
            setHealth(90);
            System.out.println("猫有九条命,不用治");
        }
    }
    public void playwithBall(){
     
        System.out.println("猫玩毛线球");
    }

    @Override
    public void eat() {
     
        setHealth(getHealth()+3);
        System.out.println("猫吃鱼,健康值加3");
    }
}

Dog

package cn.kgc.kb09;

/**
 * @Author: ChaoKeAiMuZhi
 * @Date: 2020/7/22 15:59
 * @Description:
 **/
public class Dog extends Pet {
     
    String strain;

    public String getStrain() {
     
        return strain;
    }

    public void setStrain(String strain) {
     
        this.strain = strain;
    }

    @Override
    public void toHospital() {
     
            if(getHealth()<50){
     
                setHealth(60);
                System.out.println("给狗狗治疗,吃药,打针");
            }
    }

    @Override
    public void eat() {
     
        setHealth(getHealth()+5);
        System.out.println("狗狗吃骨头,健康值加5");
    }

    public void catchFrisbee(){
     
        System.out.println("狗狗接飞盘");
    }
}

Fish:

package cn.kgc.kb09;

/**
 * @Author: ChaoKeAiMuZhi
 * @Date: 2020/7/22 16:37
 * @Description:
 **/
public class Fish extends Pet {

    @Override
    public void toHospital() {

    }

    @Override
    public void eat() {
        System.out.println("鱼吃虾米,健康值加3");
    }

}

Master:

package cn.kgc.kb09;


/**
 * @Author: ChaoKeAiMuZhi
 * @Date: 2020/7/22 16:06
 * @Description:
 **/
public class Master {
     
    //全局静态常量,只有一个副本,不会创建
    public static final String CAT="cat";
    public static final String DOG="dog";
    public static final String PENGUIN="penguin";


    public void cure(Pet p){
     
        p.toHospital();
    }

    public void feed(Pet p){
     
        p.eat();

    }

    //在返回值的部分使用多态
    //代理模式
    public Pet getPet(String type){
     
        Pet p=null;
        if(CAT.equals(type)){
     //猫类型
            p=new Cat();
        }
        if(DOG.equals(type)){
     
            p=new Dog();
        }
        if(PENGUIN.equals(type)){
     
            p= new Penguin();
        }
        return p;
    }
}

Penguin

package cn.kgc.kb09;

/**
 * @Author: ChaoKeAiMuZhi
 * @Date: 2020/7/22 15:59
 * @Description:
 **/
public class Penguin extends Pet {
     
    public void toHospital(){
     
        if(getHealth()<50){
     
            setHealth(70);
            System.out.println("给企鹅治疗,吃鱼、疗养");
        }
    }

    @Override
    public void eat() {
     
        System.out.println("企鹅吃鱼,健康值加3");
    }

    public void swim(){
     
        System.out.println("企鹅在南极游泳");
    }
}

Pet

package cn.kgc.kb09;

/**
 * @Author: ChaoKeAiMuZhi
 * @Date: 2020/7/22 15:06
 * @Description:
 **/
public abstract class Pet {
     
    private String name;
    private int health;
    private int love;

    public String getName() {
     
        return name;
    }

    public void setName(String name) {
     
        this.name = name;
    }

    public int getHealth() {
     
        return health;
    }

    public void setHealth(int health) {
     
        this.health = health;
    }

    public int getLove() {
     
        return love;
    }

    public void setLove(int love) {
     
        this.love = love;
    }

    //重写equals方法

    @Override
    public boolean equals(Object obj) {
     
        if(this==obj){
     
            return true;
        }
        if(obj instanceof Pet){
     
            Pet p=(Pet) obj;
            //自定义比较规则
            //如果宠物的名称相同,则认为是同一个对象
            if(this.name!=null && this.name.equals(p.name) && this.love!=0 &&this.love==p.love && this.health!=0 &&this.health==p.health){
     
                return true;
            }
        }
        return false;
    }

    /*@Override
    public String toString(){
        return "我叫"+this.name+",我的健康值为:"+this.health+",与主人的亲密度为:"+this.love;
    }*/

    /*@Override
    public String toString() {
        return "Pet{" +
                "name='" + name + '\'' +
                ", health=" + health +
                ", love=" + love +
                '}';
    }*/

    public abstract void  toHospital();/*{
        System.out.println("宠物去医院");
    }*/

    public abstract void eat();
}



TestMaster:

package cn.kgc.kb09;

/**
 * @Author: ChaoKeAiMuZhi
 * @Date: 2020/7/22 16:22
 * @Description:
 **/
public class TestMaster {
     
    public static void main(String[] args) {
     
        Master m=new Master();
        //Pet p=m.getPet("Dog");
        Pet p=new Cat();
        Dog d=new Dog();


        System.out.println(p);
        //涉及类型转换的时候,如果有多种可能,那么最好用instanceof关键字进行类型判断
        if(p instanceof Cat){
     
            Cat c=(Cat) p;
            c.playwithBall();
        }
        if(p instanceof Dog){
     
            Dog c=(Dog) p;
            System.out.println("转成狗类");
        }

            m.feed(d);

        m.cure(d);


        /*//出现异常java.lang.ClassCastException
        Dog d=(Dog)p;*/

    }
}


TestPet

package cn.kgc.kb09;

/**
 * @Author: ChaoKeAiMuZhi
 * @Date: 2020/7/22 15:20
 * @Description:
 **/
public class TestPet {
     
    public static void main(String[] args) {
     
        /*Pet p1=new Pet();
        Pet p2=new Pet();
        p1.setName("宠物1号");
        p2.setName("宠物1号");
        p1.setHealth(96);
        p2.setHealth(96);
        p1.setLove(92);
        p2.setLove(92);
        System.out.println(p1.toString());
        //System.out.println();默认会去调用object的toString方法,我们重写了
        System.out.println(p2);

        //System.out.println(p1==p2);
        System.out.println(p1.equals(p2));*/

        //父类引用指向子类对象
        Pet d=new Dog();//子类对象引用父类类型,多态的基础
        //这时候不能直接使用子类的属性和方法
        System.out.println(d);

        Master master=new Master();
        /*master.cure(d);

        Penguin p=new Penguin();
        master.cure(p);

        Cat c=new Cat();
        master.cure(c);

        master.feed(c);
        master.feed(d);
        master.feed(p);*/

        Pet pet=master.getPet("penguin");
        System.out.println(pet);

        if(pet instanceof Dog){
     
            Dog dog=(Dog)pet;
            dog.catchFrisbee();
        }
        if(pet instanceof Penguin){
     
            Penguin penguin=(Penguin)pet;
            penguin.swim();
        }
    }
}

你可能感兴趣的:(笔记)