代码块+继承+多态

一.代码块

	A:代码块概述
		在Java中,使用{}括起来的代码被称为代码块。
	B:代码块分类
		根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。
	C:常见代码块的应用
		a:局部代码块 
			在方法中出现;限定变量生命周期,及早释放,提高内存利用率
		b:构造代码块 
			在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
		c:静态代码块 
			在类中方法外出现,加了static修饰
			在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。

案例:

package org.westos.demo;

//代码块
public class MyTest {
    static {
        System.out.println("静态代码块");//3
    }
    {
        System.out.println("构造代码块");//4   6
    }
    public MyTest(){
        System.out.println("构造方法执行");//5  7
    }
}
class MyTest2{
    static{
        System.out.println("MyTest2的静态代码块");//1
    }
    public static void main(String[] args) {
        System.out.println("main方法执行");//2
        MyTest myTest=new MyTest();
        MyTest myTest2=new MyTest();

    }
}

注意事项:

1.代码块:就是被一对大括号{}括起来的内容
2.分类:
	1)静态代码块:
		A:在类中方法外,用static修饰
		B:随着类的加载而加载,在类的加载的时候执行,用于给类进行初始化,并且只执行一次。
		C:常常在类加载的时候在静态代码块中写准备工作的代码。
		D:只有JVM才能调用
	2)构造代码块:
		A:在类中方法外
		B:创建对象时,构造代码块和构造方法执行 ,并且在构造方法之前执行。
	3)局部代码块:
		A:在方法中出现
		B:限定变量生命周期,及早释放,提高内存利用率

二.继承

1.概述

继承:父辈的财产,子代可以继承。
Java中的继承,父类的成员,子类可以继承使用。 
要类和类具有父子关系,可以使用 extends 来实现。
继承可以提高代码的复用性和维护性。

什么时候使用继承
		继承其实体现的是一种关系:"is a" .		
		采用假设法。
			如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。

案例:

创建两个类

package org.westos.demo;

public class Cat {
    String name="小猫";
    int age=8;
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
    public void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}

package org.westos.demo;

public class Dog {
    String name="大黑";
    int age=10;
    public void lookDoor(){
        System.out.println("狗看门");
    }
    public void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}

在测试类里进行测试:

package org.westos.demo;

public class MyTest3 {
    public static void main(String[] args) {
        Cat cat=new Cat();
        System.out.println(cat.age);//8
        System.out.println(cat.name);//小猫
        cat.eat();//吃饭
        cat.sleep();//睡觉
        cat.catchMouse();//猫抓老鼠
        System.out.println("=================");

        Dog dog=new Dog();
        System.out.println(dog.age);//10
        System.out.println(dog.name);//大黑
        dog.eat();//吃饭
        dog.sleep();//睡觉
        dog.lookDoor();//狗看门
    }
}

如上:可以发现,Cat和Dog类里都有name,age公共变量和eat和sleep公共方法,可以编写一个父类存储,提高代码的复用性;只保留其特有的功能,如Cat类的catchMouse方法和Dog了的lookDoor方法

2.继承的功能

继承:就是把多个事物的共性部分,向上抽取到父类当中,以实现代码的复用性和维护性。只保留其特有的功能

案例:

package org.westos.demo2;

public class Cat extends Animal{
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}

package org.westos.demo2;

public class Dog extends Animal{
    public void lookDoor(){
        System.out.println("狗看门");
    }
}


package org.westos.demo2;

public class Animal {
    String name;
    int age;
    public void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}

package org.westos.demo2;

public class MyTest {
    public static void main(String[] args) {
        Cat cat=new Cat();
        System.out.println(cat.age);//0
        System.out.println(cat.name);//null
        cat.eat();//吃饭
        cat.sleep();//睡觉
        cat.catchMouse();//猫抓老鼠
        System.out.println("===========");

        Dog dog=new Dog();
        System.out.println(dog.age);//0
        System.out.println(dog.name);//null
        dog.eat();//吃饭
        dog.sleep();//睡觉
        dog.lookDoor();//狗看门
    }
}

3.继承的优缺点

继承的好处:提高了代码的复用性,和维护性。
不好之处:让类和类之间产生了父子关系,增加了耦合性。
软件设计的一个原则:高内聚,低耦合
高内聚:一个类独立完成某些功能的能力
耦合:完成一个功能,要去依赖别的类 类跟类之间产生了关系。
 继承的语法特点:
        1.在Java中:只支持单继承,一个类,只能有一个父类。一个父类,当然可以有多个子类。
        2.Java中也支持多层继承 自己--父亲---祖父

```java
package org.westos.demo3;

public class MyTest {
    public static void main(String[] args) {
        Son1 son1=new Son1();
        System.out.println(son1.f);//fffffffffffffffff
        System.out.println(son1.g);//ggggggggggggggggg
        son1.show();//祖父的show方法
        son1.fuShow();//父亲的fuShow方法
    }
}
class GrandFather{
    String g="ggggggggggggggggg";
    public void show(){
        System.out.println("祖父的show方法");
    }
}
class Father extends GrandFather{
    String f="fffffffffffffffff";
    public void fuShow(){
        System.out.println("父亲的fuShow方法");
    }

}
class Son1 extends Father{

}
class Son2 extends Father{

}

4.继承的注意事项

 1.父类的私有成员,子类不能继承。
 2.构造方法不参与继承。
 3.不要为了部分功能而去继承

案例:

package org.westos.demo4;

public class MyTest {
    public static void main(String[] args) {
        Zi zi=new Zi();
        //System.out.println(zi.name);//报错,私有变量子类不能继承
        zi.show();//子类的show方法执行了
        System.out.println(zi.age);//0
        //zi.show1();//报错,私有成员子类不能继承
    }
}

class Fu{
    public Fu() {
    }

    private String name="张三";
    int age;
    public void show(){
        System.out.println("父类的show方法执行了");
    }
    private void show1(){
        System.out.println("父类的私有show方法执行了");
    }
}

class Zi extends Fu{
    public void show(){
        System.out.println("子类的show方法执行了");
    }
}

5.super和this关键字

1).概述

 super:表示的是父类的空间标识,你可以理解为父类的一个引用,或者说是对象。
        我们就可以使用super这个关键字,去访问父类的数据
        super和this
        访问父类的成员变量: super.成员变量名;
        访问本类的成员变量: this.成员变量名;
        访问父类的成员方法: super.成员方法名();
        访问本类的成员方法: this.成员方法名();
        访问父类的构造方法: super();
        访问本类的构造方法: this();

案例:

package org.westos.demo5;

public class MyTest {
    public static void main(String[] args) {
        Zi zi=new Zi();
        zi.test();
    }
}
class Fu{
    String name="爸爸";
    int age=50;
    public void fuShow(){
        System.out.println("父类的show方法");
    }
}
class Zi extends Fu{
    String name="儿子";
    int age=18;
    public void ziShow(){
        System.out.println("子类的show方法");
    }
    public void test(){
        System.out.println(this.name);//儿子
        System.out.println(this.age);//18
        System.out.println(super.name);//爸爸
        System.out.println(super.age);//50
        this.fuShow();//父类的show方法
        this.ziShow();//子类的show方法
        super.fuShow();//父类的show方法
    }


}

6.继承中构造方法之间的关系

1).概述

子类中所有的构造方法默认都会访问父类中空参数的构造方法
  当我在创建子类对象时,为什么回先去去调用父类的构造方法?
         因为有了继承关系后,当我们去初始化子类的 时候,子类要继承父类的一些数据,你子类既然要 继承父类的数据,甚至还要去使用父类的数据
         如果说这个时候,父类的数据并没有完成初始化,你子类怎么用
         所以,我们在创建子类对象的时候,就会先调用父类的构造方法,来完成父类数据的初始化,然后在初始化自己的数据。
         
         我们在什么时候,去调用的父类构造呢?
         在每个类的构造方法中的第一行,有一行默认代码 super() 这行代码就去调用了父类的空参构造。
        
        在Java中有一个顶层 父类 Object 这个类就是老祖宗类,所有的类,都是直接或间接继承自他。

案例一:

package org.westos.demo6;

public class MyTest {
    public static void main(String[] args) {
        //执行结果:
        // 父类构造方法执行了
        //子类构造方法执行了
        Zi zi=new Zi();
    }
}
class Fu extends Object{
    int fuNum=100;
    public Fu(){
        super();
        System.out.println("父类构造方法执行了");
    }
}
class Zi extends Fu{
    int ziNum=200;
    public Zi() {
        super();
        System.out.println("子类构造方法执行了");
    }
}

2).问题分析

当我们创建子类对象时,子类的构造方法的第一行,会默认去调用父类的空参构造,但是如果说,父类没有空参构造怎么办?
此时子类的空参构造也会报错,只能用super调用父类的有参构造
1)给父类提供一个空参构造。
2)想办法去调用父类的有参构造。

案例二:

package org.westos.demo7;

public class MyTest {
    public static void main(String[] args) {
        //Zi zi=new Zi();
        Zi zi1=new Zi(3000);

    }
}
class Fu{
   /* public Fu() {
        System.out.println("父类的空参构造执行了");
    }*/
    public Fu(int num){
        System.out.println("父类的有参构造执行了");
    }
}
class Zi extends Fu{
    public Zi() {
        super(100);
        System.out.println("子类的空参构造执行了");
    }
    public Zi(int num){
        //super(1000);
        this();//先去访问本类的构造方法,然后通过super再去访问父类的有参构造
        System.out.println("子类的有参构造执行了");
    }
}

执行结果:

父类的有参构造执行了
子类的空参构造执行了
子类的有参构造执行了

3).注意事项

1.父类没有无参构造方法,子类怎么办?
		a: 在父类中添加一个无参的构造方法
		b:子类通过super去显示调用父类其他的带参的构造方法
		c:子类通过this去调用本类的其他构造方法
			本类其他构造也必须首先访问父类构造
2.super(…)或者this(….)必须出现在构造方法的第一条语句上

4).经典的面试题

class Fu{
			public int num = 10;
			public Fu(){
				System.out.println("fu");
			}
		}
		class Zi extends Fu{
			public int num = 20;
			public Zi(){
				System.out.println("zi");
			}
			public void show(){
				int num = 30;
				System.out.println(num);//30
				System.out.println(this.num);//20
				System.out.println(super.num);//10
			}
		}
		class Test {
			public static void main(String[] args) {
				Zi z = new Zi();
				z.show();
			}
		}
class Fu {
			static {
				System.out.println("静态代码块Fu");  //1
			}
	
			{
				System.out.println("构造代码块Fu"); //3
			}
	
			public Fu() {
				System.out.println("构造方法Fu"); //4
			}
		}
	
		class Zi extends Fu {
			static {
				System.out.println("静态代码块Zi"); //2
			}
	
			{
				System.out.println("构造代码块Zi"); //5
			}
	
			public Zi() {
				super();
				System.out.println("构造方法Zi"); //6
			}
		}
		
		class Test{
			public static void main(String[] args){
				Zi z = new Zi(); 
			}
		}

7.方法重写

1).继承中成员方法的关系

当子类和父类出现了一模一样的方法的时候(方法名,参数 返回值一样)就会发生方法覆盖现象,称之为方法重写。
子类方法会覆盖父类方法。
为什么要有方法重写:子类对父类的功能实现,并不是很满意,子类想要改写掉父类的功能,或者说想要扩展父类的功能。那么子类都可以使用方法重写来完成

		a:当子类的方法名和父类的方法名不一样的时候
		b:当子类的方法名和父类的方法名一样的时候
			通过子类调用方法:
				a: 先查找子类中有没有该方法,如果有就使用
				b:在看父类中有没有该方法,有就使用
				c: 如果没有就报错
package org.westos.demo8;

public class MyTest {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.fuShow();//父类show方法执行了
        zi.ziShow();//子类show方法执行了
        zi.eat();//子类的吃饭方法
    }
}

class Fu{
    public void fuShow(){
        System.out.println("父类show方法执行了");
    }
    public void eat(){
        System.out.println("父类的吃饭方法");
    }
}
class Zi extends Fu{
    public void ziShow(){
        System.out.println("子类show方法执行了");
    }

    @Override
    public void eat() {
        System.out.println("子类的吃饭方法");
    }
}

2).方法重写的概述

A:什么是方法重写
		子类中出现了和父类中一模一样的方法声明(方法名,参数列表,返回值类型),也被称为方法覆盖,方法复写。
	B: Override和Overload的区别?Overload能改变返回值类型吗?
	重载是在一个类中,方法名相同,参数列表不同,与返回值无关
	重写是指子类对父类的覆盖重写,方法名相同,参数列表相同,只是方法的方法体不同
	C:方法重写的应用:
		当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
		这样,即沿袭了父类的功能,又定义了子类特有的内容。

案例一:

package org.westos.demo9;

public class MyTest {
    public static void main(String[] args) {
        Dog dog=new Dog();
        dog.eat();//狗喜欢吃骨头
        dog.sleep();//狗喜欢晚上睡觉
        System.out.println("======");
        Cat cat=new Cat();
        cat.eat();//猫吃鱼
        cat.sleep();//猫白天睡觉
    }
}
class Animal{
    public void eat(){
        System.out.println("吃饭");
    }
    public void  sleep(){
        System.out.println("睡觉");
    }
}
//子类对父类的方法不满意,可以对方法进行覆盖重写,重写后调用以子类方法为准
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void sleep() {
        System.out.println("猫白天睡觉");
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗喜欢吃骨头");
    }

    @Override
    public void sleep() {
        System.out.println("狗喜欢晚上睡觉");
    }
}

案例二:

package org.westos.demo9;

public class Phone {
    public void call(){
        System.out.println("打电话");
    }
    public void sendMsg(){
        System.out.println("发短信");
    }
}
class IPhone extends Phone{
    //Override注解可以检测是否为方法的重写
    @Override
    public void call() {
        System.out.println("给刘亦菲打电话");
    }
}
class HuaWei extends Phone{
    @Override
    public void sendMsg() {
        System.out.println("给刘亦非发短信");
    }
}

package org.westos.demo9;

public class MyTest2 {
    public static void main(String[] args) {
        IPhone iPhone=new IPhone();
        iPhone.call();//给刘亦菲打电话

        HuaWei huaWei=new HuaWei();
        huaWei.sendMsg();//给刘亦非发短信
    }
}

3).重写的注意事项

1.父类私有的方法子类不能重写,因为私有的方法,子类都不能继承何谈重写。
2.子类在重写父类方法时,方法前面的权限修饰符,不能比父类方法的权限修饰符的低。可以比父类的高,也可以一样,最好一样
public>protected>缺省的>private
3.静态方法,不参与重写

案例一:

package org.westos.demo91;

public class MyTest {
    public static void main(String[] args) {
		Zi zi = new Zi();
        zi.show2();
        Zi.fuStatic();
        Fu.fuStatic();
    }
}
class Fu{
    public static void fuStatic(){
        System.out.println("父类的静态方法");
    }

    private void show(){
        System.out.println("父类私有的静态方法");
    }

    protected void show2(){
        System.out.println("666");
    }
}
class Zi extends Fu{
    //这里使用Override检测会报错,说明静态方法不能被重写
   /* @Override
    public static void fuStatic(){
        System.out.println("子类的静态方法");
    }*/

   //同样使用Override检测依旧会报错
   /*@Override
    private void show(){
        System.out.println("子类私有的静态方法");
    }*/
   
   
    //同样报错
//    private void show2(){
//        System.out.println("666");
//    }
}

案例二:

package org.westos.demo92;

public class MyTest {
    public static void main(String[] args) {
        Student student = new Student();
        student.age=88;
        student.name="张三";
        System.out.println(student.age);//88
        System.out.println(student.name);//张三
        student.eat();//学生吃辣条
        student.sleep();//学生爱睡懒觉
        student.study();//学生的工作是学习
        System.out.println("==============");
        Teacher teacher=new Teacher();
        teacher.age=66;
        teacher.name="李四";
        System.out.println(teacher.age);//66
        System.out.println(teacher.name);//李四
        teacher.eat();//老师喜欢吃腊肠
        teacher.sleep();//老师不喜欢睡觉
        teacher.teach();//老师的工作是教书
    }
}

class Person {
    String name;
    int age;
    public void eat() {
        System.out.println("吃饭");
    }

    public void sleep() {
        System.out.println("睡觉");
    }


}

class Student extends Person {
    @Override
    public void eat() {
        System.out.println("学生吃辣条");
    }

    @Override
    public void sleep() {
        System.out.println("学生爱睡懒觉");
    }
    public void study(){
        System.out.println("学生的工作是学习");
    }

}

class Teacher extends Person {
    @Override
    public void eat() {
        System.out.println("老师喜欢吃腊肠");
    }

    @Override
    public void sleep() {
        System.out.println("老师不喜欢睡觉");

    }
    public void teach(){
        System.out.println("老师的工作是教书");
    }
}

8.final关键字

1)概述:

A:为什么会有final
		由于继承中有一个方法重写的现象,而有时候我们不想让子类去重写父类的方法.这对这种情况java就给我们提供了一个关键字: final
	B:final概述
		final关键字是最终的意思,可以修饰类,变量,成员方法。
		分别表示类不可继承,变量不可改变,方法不可重写

2.final修饰特点:

		修饰类:		被修饰类不能被继承
		修饰方法:	被修饰的方法不能被重写
		修饰变量:	被修饰的变量不能被重新赋值,因为这个量其实是一个常量
注意:
		基本类型,是值不能被改变
		引用类型,是地址值不能被改变

案例:

package org.westos.demo93;

public class MyTest {
    public static void main(String[] args) {
        final int num=1000;
        //报错,final修饰的num为一个常量,不可改变
       // num=2000;
       
//final 修饰引用类型,指的是 地址值不能再次改变
        final Iphone iphone=new Iphone();
        //iphone=new Iphone();
    }
}

class Phone{
    public final void show(){
        
    }
}
class Iphone extends Phone{
    //报错,带final修饰的方法不能被重写
    /*public final void show(){

    }*/
}
final class Animal{

}
//报错,带有final修饰的类不能继承
//class Dog extends Animal{}

三.多态

1.概述

1)多态的概念:
指的是一种事物,在不同时期,所表现出的不同状态。
如:
猫 就是 一只猫,猫是一只动物
Cat cat=new Cat();
Aniaml an=new Cat();
 狗就是狗类型,狗是动物类型。
 Dog  dog= new Dog();
Aniaml an=new Dog();
2)多态的前提:
		a:要有继承关系。
		b:要有方法重写。 其实没有也是可以的,但是如果没有这个就没有意义。
		c:要有父类引用指向子类对象。
			父 f =  new 子();
			 Animal an=new Cat();

案例:

package org.westos.demo;

public class MyTest {
    public static void main(String[] args) {
        //使用多态
        Animal animal=new Cat();
        animal.eat();//猫吃鱼
        animal.sleep();//猫白天睡觉

        Animal animal1=new Dog();
        animal1.sleep();//狗晚上睡觉
        animal1.eat();//狗吃骨头
    }
}
class Animal{
    public void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    @Override
    public void sleep() {
        System.out.println("猫白天睡觉");
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    @Override
    public void sleep() {
        System.out.println("狗晚上睡觉");
    }
}

2.多态中的成员访问特点

		a:成员变量
			编译看左边,运行看左边。
			采用多态的形式,去访问成员变量,访问的是父类的成员变量
		b:构造方法
			创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。
		c:成员方法
			编译看左边,运行看右边。
			如果子类没有重写父类的方法,就以父类的方法为准,如果子类重写了父类的方法,那么运行时,会以子类重写过后的为准。
		d:静态方法
			编译看左边,运行看左边。
			(静态和类相关,算不上重写,所以,访问还是左边的)
			静态方法不参与重写

案例:

package org.westos.demo;

public class MyTest2 {
    public static void main(String[] args) {
        Animal2 an=new Cat2();
        //1.多态访问成员变量
        System.out.println( an.age);//333
        System.out.println( an.name);//动物

        //2.多态访问构造方法
        //创建子类对象的时候,会访问父类的构造方法,对父类的数据进行初始化。

        //3.多态访问成员方法
        //如果子类没有重写父类的方法,就以父类的方法为准,如果子类重写了父类的方法,那么运行时,会以子类重写过后的为准。
        an.show();//猫的重写show方法

        //4.多态访问静态方法
        an.staticShow();//父类的静态show方法
    }
}
class Animal2{
    public Animal2() {
        System.out.println("动物的构造方法");
    }

    String name="动物";
    int age=333;

    public static void staticShow(){
        System.out.println("父类的静态show方法");
    }

    public void show(){
        System.out.println("动物的show方法");
    }

    public void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}
class Cat2 extends Animal2{

    String name="猫";
    int age=666;

    public Cat2() {
        System.out.println("猫的构造方法");
    }

    @Override
    public void show() {
        System.out.println("猫的重写show方法");
    }

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    @Override
    public void sleep() {
        System.out.println("猫白天睡觉");
    }
}
class Dog2 extends Animal2 {
    String name="狗";
    int age=999;

    public Dog2() {
        System.out.println("狗的构造方法");
    }

    @Override
    public void show() {
        System.out.println("狗的重写的show方法");
    }

    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    @Override
    public void sleep() {
        System.out.println("狗晚上睡觉");
    }
}

3.多态的好处

		a:提高了代码的复用性(继承保证)
		b:提高了代码的扩展性(由多态保证) 

案例:

package org.westos.demo2;

public class MyTest {
    public static void main(String[] args) {
        //在测试类中,一般只需要提供程序的入口就可以了
        Dog dog=new Dog();
        dog.eat();//狗吃骨头
        MyUtils.testEat(dog);
        Cat cat=new Cat();
        cat.eat();//猫吃鱼
        MyUtils.testEat(cat);
        Tiger tiger=new Tiger();
        tiger.eat();//老虎吃肉
        MyUtils.testEat(tiger);
    }
}
class Animal{
    public void eat(){
        System.out.println("动物吃饭");
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
class Tiger extends Animal{
    @Override
    public void eat() {
        System.out.println("老虎吃肉");
    }
}

package org.westos.demo2;
//设计一个工具类
public class MyUtils {
    //通过方法重载,来设计这个工具类。扩展性不好。因为每增加一种动物。就得在工具类中提供一个重载方法
    //私有化构造,表示此类不能直接被实例化,需要通过静态方法直接调用
    private MyUtils() {
    }
    public static void testEat(Animal an){
        an.eat();
    }
    public static void testEat(Cat cat){
        cat.eat();
    }
    public static void testEat(Dog dog) {
        dog.eat();
    }
    public static void testEat(Tiger tiger){
        tiger.eat();
    }
    }


分析:使用多态的话,可以直接传递一个animal进去进行接收 ,不用每一次增加一种动物,都要提供一个重载方法,这样的话,编译看左,运行看右,即编译时的参数为animal,有`eat方法,不报错;运行时传一个具体的参数,cat,执行具体的方法.

4.多态的弊端

不能直接调用子类特有的功能
如何解决:
如果要调用子类特有的方法,我们可以向下转型
向上转型:把子类型,转换成父类型。多态就是向上转型。

案例:

package org.westos.demo3;


public class MyTest {
    public static void main(String[] args) {
        Animal an = new Cat();
        an.eat();
        //报错,多态不能直接调用子类特有的功能
        //an.show();

        //如果要调用子类特有的方法,我们可以向下转型
        Animal an2 = new Cat();
        Cat cat = (Cat) an2;
        cat.show();

        Dog dog=(Dog) an2;//会报一个异常,ClassCastException 类型转换异常

        //向上转型:把子类型,转换成父类型。多态就是向上转型。

    }
}

class Animal {
    public void eat() {
        System.out.println("动物吃饭");
    }
}

class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void show() {
        System.out.println("猫展腿");
    }
}
class Dog extends Animal {
        @Override
        public void eat() {
            System.out.println("狗吃骨头");
        }
    }


5.多态的内存图解

在这里插入图片描述

6.两道经典面试题

A:看下面程序是否有问题,如果没有,说出结果
		class Fu {
			public void show() {
				System.out.println("fu show");
			}
		}
	
		class Zi extends Fu {
			public void show() {
				System.out.println("zi show");
			}
	
			public void method() {
				System.out.println("zi method");
			}
		}
	
		class DuoTaiTest3 {
			public static void main(String[] args){
				Fu f = new Zi();
	
				f.method();
				f.show();
			}
	
	}:父类中没有method方法,编译报错

	B:看下面程序是否有问题,如果没有,说出结果
		class A {
			public void show() {
				show2();
			}
			public void show2() {
				System.out.println("我");
			}
		}
		class B extends A {
			public void show2() {
				System.out.println("爱");
			}
		}
		class C extends B {
			public void show() {
				super.show();
			}
			public void show2() {
				System.out.println("你");
			}
		}
		public class DuoTaiTest4 {
			public static void main(String[] args) {
				A a = new B();
				a.show();
				
				B b = new C();
				b.show();
			}
		}: 爱 你
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值