继承与多态1

分卷写吧,感觉有点长

继承

     继承主要解决的问题是:共性的抽取,实现代码复用。

public class Cat {
    public String name;
    public  int age ;

    public void eat() {
        System.out.println (this.name + "正在吃饭");

    }
    public void mimi(){
        
        System.out.println (this.name + "正在叫");
    }
}
public class Dog {
    public String name;
    public  int age ;
    public void eat(){

        System.out.println (this.name + "正在吃饭");
    }
    public void beak(){

        System.out.println (this.name + "正在叫");
    }
}
public class Test {
    public static void main(String[] args){
    Dog dog = new Dog();
    dog.name = "大黄";
    dog.age = 1;
    dog.eat();
    dog.beak();
        System.out.println ("=======");
    Cat cat = new Cat();
    cat.name = "虎";
    cat.age = 2;
    cat.eat();
    cat.mimi();


}
}

以上代码中,Cat类和Dog类有许多相同的地方:

public String name;
    public  int age ;

    public void eat() {
        System.out.println (this.name + "正在吃饭");
}

     这些相同的成员变量和方法能不能将他们提取出来,放在一个共用的类当中。  

     当我们想实现这种方法时,这就要用到继承的关键字extends

这是继承的写法。 

public class 子类 extends 父类{

}

     先放代码:

public class Animal {
    public String name;
    public  int age ;

    public void eat() {
        System.out.println (this.name + "正在吃饭");

    }

public class Dog extends Animal {
   
    public void beak(){

        System.out.println (this.name + "正在叫");
    }
}

public class Cat extends Animal{

    public void mimi(){

        System.out.println (this.name + "正在叫");
    }
}

public class Test {
    public static void main(String[] args){
    Dog dog = new Dog();
    dog.name = "大黄";
    dog.age = 1;
    dog.eat();
    dog.beak();
        System.out.println ("=======");
    Cat cat = new Cat();
    cat.name = "虎";
    cat.age = 2;
    cat.eat();
    cat.mimi();


}
}

       这样,可以通过继承,让子类调用父类的成员。继承之后,子类可以使用父类中的成员,子类在实现时只需关心自己成员即可。 

       注意:子类里面一定要有自己的变量!不然父类定义的没有意义

       换个简单点的例子:

public class Derievd extends Base {
    public int c = 3;
    public void func(){
        Derievd derievd = new Derievd();
        System.out.println (a);
        System.out.println (b);
        System.out.println (c);
      }
  }
public class Base {
    public int a = 1;
    public int b = 2;
}

public class Test {

public static void main(String[] args) {
   Derievd derievd = new Derievd();
   derievd.func();
}
}

       运行结果 :

      这之中,a、b是Derievd自己的成员变量,c是从Base中继承过来的成员变量这时可以看成属于Derievd,用this.引用c也是属于Derievd。

       我们改一下看看会有什么变化:

public class Derievd extends Base {
    public int c = 3;
    public int a =100;
    public void func(){
        Derievd derievd = new Derievd();
        System.out.println (this.a);
        System.out.println (this.b);
        System.out.println (this.c);
      }
  }
public class Base {
    public int a = 1;
    public int b = 2;
}

public class Test {

public static void main(String[] args) {
   Derievd derievd = new Derievd();
   derievd.func();
}
}

       运行结果:

       可知,用this.调用子类和父类有同名变量时候,优先调用子类的变量。当想调用父类的变量时候要用super.来调用父类的成员。

重写

      在父类与子类里面,有方法相同;参数列表(个数、类型、顺序)相同;返回值相同,时候,我们称这个方法发生了重写。


public class Animal {
    public String name;
    public int age;
    public  Animal(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void eat() {

        System.out.println(this.name + "正在吃饭");
    }

}


public class Dog extends Animal {
    public Dog(String name,int age){
            super(name,age);
    }
    public void eat(){
        System.out.println (  this.name +"正在吃");
    }
}


public class Test {
    public static void main(String[] args){
        Animal animal = new Dog("张三",12);
        animal.eat();


}

 上面方法就构成了重写:

      通过向上转型父类的引用,打印出来子类和父类中被重写的方法。我们可以认为被重写的方法子类的地址传到了父类的方法中。

ps:@Override  看到这个符号就是提示你这个方法被重写了。

      这种调用父类方法打印子类的方法的叫动态绑定

      理解动态绑定,是后续学习多态的基础。

注意:        

      1.不能重写静态方法。

      2.方法不能被final修饰(final有不可变性,无法被重写)

      3子类权限要大于等于父类权限。

      4.private修饰的方法不能被重写(封装)

      5.被重写的方法返回值类型可以不同,但是必须是具有父子关系的。

重写设计原则

       对于已经投入使用的类,尽量不要进行修改。最好的方式是:重新定义一个新的类,来重复利用其中共性的内容, 并且添加或者改动新的内容。

其他

静态绑定:在编译时,根据所传递实参类型就确定了具体调用那个方法。(重载)

动态绑定:在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用那个类的方法。(重写)

向上转型.直接赋值

向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。

语法格式:父类类型 对象名 = new 子类类型()

Animal animal = new Dog("张三",12);
        animal.eat();

      父类类型的引用子类对象,直接调用父类方法。

      缺点:只能调用父类自己的方法。 

向下转型

      将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换。

      Java中为了提高向下转型的安全性,引入 了 instanceof ,如果该表达式为true,则可以安全转换。

if(animal instanceof Dog){
cat = (Dog)animal;
Dog.eat();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值