精华内容
下载资源
问答
  • java语言之继承与多态
    2021-03-13 20:25:40

    详解Java面向对象中的继承与多态

    发布时间:2020-12-01 16:53:06

    来源:亿速云

    阅读:74

    作者:Leah

    详解Java面向对象中的继承与多态?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

    Java 继承与多态的深入理解

    1、  什么是继承,继承的特点?

    子类继承父类的特征和行为,使得子类具有父类的各种属性和方法。或子类从父类继承方法,使得子类具有父类相同的行为。

    特点:在继承关系中,父类更通用、子类更具体。父类具有更一般的特征和行为,而子类除了具有父类的特征和行为,还具有一些自己特殊的特征和行为。

    在继承关系中。父类和子类需要满足is-a的关系。子类是父类。

    表示父类和子类的术语:父类和子类、超类和子类、基类和派生类,他们表示的是同一个意思。

    2、  为什么需要继承?什么时候应该继承?

    使用继承可以有效实现代码复用,避免重复代码的出现。

    当两个类具有相同的特征(属性)和行为(方法)时,可以将相同的部分抽取出来放到一个类中作为父类,其它两个类继承这个父类。

    继承实现了面向对象的原则:write once,only once(编写一次、且编写一次

    3、  如何实现继承?

    在Java语言中,用extends(扩展)关键字来表示一个类继承了另一个类。

    在父类中只定义一些通用的属性和方法。

    子类自动继承父类的属性和方法,子类中可以定义特定的属性和方法。或子类重新定义父类的属性、重写父类的方法可以获得与父类不同的功能。

    4、  什么是方法重写?

    如果在子类中定义的一个方法,其名称、返回类型及参数列表正好与父类中某个方法的名称、返回类型及参数列表相匹配,那么可以说,子类的方法重写了父类的方法。

    方法重写在不同类,是实现多态的必要条件。

    5、  super关键字的用法和位置,super关键字调用父类的构造方法,super关键字调用父类的方法?

    在子类的构造方法中,通过super关键字调用父类的构造方法。

    如果子类中重写了父类的方法,可以通过super关键字调用父类的方法。

    父类:private String name;

    private String sex;

    public xinxin1(String name,String sex)

    {

    this.name=name;

    this.sex=sex;

    }

    public void hello(){

    System.out.println(“嗨!我是”+name+”我是”+sex+”孩”);

    }

    子类:public xinxin2(String name,String sex)

    {

    //调用父类的构造方法

    super(name,sex);

    }

    public void hello(){

    System.out.println(“我是新来的!”);

    //调用父类的方法

    super.hello();

    }

    位置注意:调用父类的构造方法的语句(super语句)必须是构造方法中的第一条语句。

    因为创建对象的时候,需要先创建父类对象,再创建子类对象。

    注意:创建对象时,先创建父类对象,在创建子类对象。如果没有显示调用父类的构造方法,将自动调用父类的无参构造方法。

    6、  一切类的老大(祖先)Object。

    所有类都直接或者间接地继承了java.lang.Object类,Object类中定义了所有的java对象都具有的相同行为,是所有类的祖先。

    一个类如果没有使用extends关键字,那么这个类直接继承自Object类。

    7、  什么是多态?

    多态的特征是表现出多种形态,具有多种实现方式。或者多态是具有表现多种形态的能力的特征。或者同一个实现接口,使用不同的实例而执行不同的操作。

    8、  为什么需要使用多态?多态的好处?

    可以增强程序的可扩展性及可维护性,使代码更加简洁。

    不但能减少编码的工作量,也能大大提高程序的可维护性及可扩展性。

    9、  如何实现多态?

    一般做法是:写一个方法,它只接收父类作为参数,编写的代码只与父类打交道。调用这个方法时,实例化不同的子类对象(new 一个对象)。

    更具体的说:

    (1)、子类重写父类的方法。使子类具有不同的方法实现。

    (2)、把父类类型作为参数类型,该父类及其子类对象作为参数转入。

    (3)、运行时,根据实际创建的对象类型动态决定使用那个方法。

    在运行时,java虚拟机会根据实际创建的对象类型决定使用那个方法。一般将这称为动态绑定。

    10、多态小结:

    多态与继承、方法重写密切相关,我们在方法中接收父类类型作为参数,在方法实现中调用父类类型的各种方法。当把子类作为参数传递给这个方法时,java虚拟机会根据实际创建的对象类型,调用子类中相应的方法(存在方法重写时)。

    关于详解Java面向对象中的继承与多态问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

    更多相关内容
  • java继承与多态

    2018-06-01 10:55:10
    Java继承与多态专题讲解,详细生动,例子丰富,适合初学者
  • 精选文库 PAGE PAGE 2 西 安 邮 电 大 学 计算机学院 课内实验报告 实验名称 继承...通过编程和上机实验理解 Java 语言继承多态特性掌握变量的隐藏方法的覆盖重载掌握抽象类和接口的使用 二实验要求 1.编写体现类的
  • 头歌实践-Java继承与多态

    千次阅读 2021-10-28 19:18:19
    头歌实践作业第1关:练习-Java继承多态之final关键字第2关:学习-Java继承多态之对象类型的转换任务描述相关知识向上转型向下转型编程要求第3关:练习-Java继承多态之方法重载任务描述编程要求第4关:练习-...

    第1关:练习-Java继承和多态之final关键字

    /**
     * 按照代码文件中提供的注释完成 Demo 类的编写,使得程序正常输出。
     */
    class DemoTest{
        int i = 10;
    }
    // 请在下面的Begin-End之间按照注释中给出的提示编写正确的代码
    /********* Begin *********/
    
    // 将Demo类改为 final形式
    final class Demo{
        // 定义一个final、static常量,名为PI,值为3.14
    	final static double PI=3.14;
        // 声明一个final类型的DemoTest对象,命名为demoTest
    	 final DemoTest demoTest = new DemoTest();//这里声明时应该初始化
    	
        // 声明一个不为final类型的DemoTest对象,命名为demoTest2
    	DemoTest demoTest2;
        // 声明一个final型的数组,类型为int,值为 1,2,3,命名为a
    	final int []a=new int[]{1,2,3};
        // 删除主函数中错误的代码,使得程序能够正确输出
        public static void main(String[] args) {
            Demo demo = new Demo();
            //demo.demoTest = new Test();
            //demo.PI = 20;//final变量一经定义赋值则不可以改变
            System.out.println(demo.PI);
            demo.demoTest2 = new DemoTest();
            System.out.println(demo.demoTest2.i);
            for (int i = 0; i < demo.a.length; i++){
                demo.a[i] = 9;
                System.out.println(demo.a[i]);
            }
        }
    }
    /********** End **********/
    

    第2关:学习-Java继承和多态之对象类型的转换

    任务描述

    本关任务:使用对象类型的转换,根据编程提示,完成猫类和动物类的转换,以及彼此方法和属性的调用。

    相关知识

    在之前的学习任务中,我们学习了基本类型之间的转换,这里我们来为大家介绍对象间的类型转换。

    Java 语言允许某个类型的引用变量引用子类的实例,而且可以对这个引用变量进行类型转换。如果把引用类型转换为子类类型,则称为向下转型;**如果把引用类型转换为父类类型,则称为向上转型。**注意:两者必须为父子关系。

    向上转型

    把子类对象赋值给父类类型的变量(隐式转换,不用进行强制类型转换),被称为向上转型。

    本质:父类的引用指向了子类的对象。

    语法:

    父类类型 引用名 = new 子类类型() ;

    例如:狗是动物的一种,那么也可以将狗看成一个动物对象。

    class Animal{
        public void info(){
            System.out.println("我是动物");
        }
    }
    class Dog extends Animal{
        public void eat(){
            System.out.println("狗在吃东西");
        }
        public static void main(String[] args) {
            Animal animal = new Dog(); // 向上转型
            animal.info();
        }
    }
    

    执行结果:

    我是动物

    狗对象可以调用该方法,那么同样猫也可以调用该方法,这就做到了在父类中定义一个方法可以完成各个子类的功能。由于向上转型是一个从较具体类到较抽象类的转换,所以它总是安全的,因为我们可以说狗是动物,但是不能说动物是狗。

    向上转型的特点如下:

    1. 向上转型对象不能操作子类新增的成员变量(失掉了这部分属性),不能使用子类新增的方法(失掉了一些功能);

    2. 向上转型对象可以操作子类继承或重写的成员变量,也可以使用子类继承的或重写的方法;

    3. 如果子类重写了父类的某个方法后,当对象的向上转型对象调用这个方法时一定是调用了这个重写的方法,因为程序在运行时知道,这个向上转型对象的实体是子类创建的,只不过损失了一些功能而已。

    向下转型

    向下转型是指子类引用父类对象,就是将父类对象能转换成子类对象,这时需要满足两个条件:一是必须执行强制类型转换;二是必须确保父类对象是子类的一个实例,否则抛出异常。

    语法:

    子类类型 引用名 = (子类类型)父类引用;

    class Animal{
        public void info(){
            System.out.println("我是动物");
        }
    }
    class Dog extends Animal{
        public void eat(){
            System.out.println("狗在吃东西");
        }
        public static void main(String[] args) {
            Animal animal = new Dog(); // 向上转型
            Dog animal1 = (Dog) animal; // 向下转型
            animal1.eat();
        }
    }
    

    执行结果:

    狗在吃东西

    向下转型的特点如下:

    1. 向下转型对象可以操作父类及子类成员变量和成员方法;

    2. 向下转型对象访问重写父类的方法时,操作的是子类的方法;

    3. 向下转型必须进行强制类型转换;

    4. 向下转型必须保证父类对象引用的是该子类的对象,如果引用的是父类的其他子类对象,会抛出类型不匹配异常。

    编程要求

    仔细阅读右侧编辑区内给出的代码框架及注释,在 Begin-End 中完成猫类和动物类的转换,以及彼此方法和属性的调用,具体要求如下:

    把猫类对象赋值给动物类;
    将动物类引用转换为猫类对象;
    输出 Animal 类的 name 变量;
    输出 Animal 类的 staticName 变量;
    输出 Cat 类的 eat() 方法;
    输出 Animal 类的 staticEat() 方法;
    调用 Cat 类的 str 变量;
    调用 Cat 类的 eatMethod() 方法。

    /**
     * 使用对象类型的转换,根据编程提示,完成猫类和动物类的转换,以及彼此方法和属性的调用
     * 	把猫类对象赋值给动物类;
    	将动物类引用转换为猫类对象;
    	输出 Animal 类的 name 变量;
    	输出 Animal 类的 staticName 变量;
    	输出 Cat 类的 eat() 方法;
    	输出 Animal 类的 staticEat() 方法;
    	调用 Cat 类的 str 变量;
    	调用 Cat 类的 eatMethod() 方法。
     */
     // 定义动物类
    class Animal{
    	// 定义动物类的属性
        public String name = "动物";
        public static String staticName = "可爱的动物";
        // 定义动物类的行为方法
        public void eat() {
            System.out.println("动物吃饭");
        }
        public static void staticEat() {
            System.out.println("可爱的动物正在在吃饭");
        }
    }
    // 定义猫类,该类继承动物类
    public class Cat extends Animal{
    	// 定义猫类的属性
        public String name = "猫";
        public String str = "可爱的小猫";
        public static String staticName = "我是喵星人";
        // 定义猫类的行为方法
        public void eat() {
            System.out.println("猫吃饭");
        }
        public static void staticEat() {
            System.out.println("喵星人在吃饭");
        }
        public void eatMethod() {
            System.out.println("猫喜欢吃鱼");
        }
    
        public static void main(String[] args) {
            // 请在下面的Begin-End之间按照注释中给出的提示编写正确的代码
            /********* Begin *********/
            // 向上转型,把猫类对象赋值给动物类
        	Animal animal =new Cat();
            // 向下转型,将动物类引用转换为猫类对象
        	Cat cat2=(Cat) animal;
            // 输出Animal类的name变量
        	System.out.println(animal.name);
            // 输出Animal类的staticName变量
        	//直接通过类名访问静态变量
        	System.out.println(Animal.staticName);
            // 输出Cat类的eat()方法
        	animal.eat();
            // 输出Animal类的staticEat()方法
        	Animal.staticEat();
            // 调用Cat类的str变量
        	System.out.println(cat2.str);
            // 调用Cat类的eatMethod()方法
        	cat2.eatMethod();
            /********** End **********/
        }
    }
    
    
    
    
    

    第3关:练习-Java继承和多态之方法重载

    任务描述

    本关任务:定义名为 print 的静态方法,携带一个参数,无论该参数是 int 型、double 型还是字符串型,都可以将该参数进行打印。

    编程要求

    仔细阅读右侧编辑区内给出的代码框架及注释,按照提示编写程序代码。

    
    /**
     * 任务:定义名为 print 的静态方法,携带一个参数,
     * 无论该参数是 int 型、double 型还是字符串型,都可以将该参数进行打印。
     */
    public class Print {
        // 请在下面的Begin-End之间编写正确的代码
        /********** Begin **********/
    	static void print(int num) {
    		System.out.println(num);
    	}
    	static void print(double num) {
    		System.out.println(num);
    	}
    	static void print(String str) {
    		System.out.println(str);
    	}
    	
    	public static void main(String []args) {
    		Print.print(16);
    		Print.print(16.0);
    		Print.print("16");
    	}
    
        /********** End **********/
    }
    

    第4关:练习-Java继承和多态之方法重写

    任务描述

    本关任务:计算球的表面积。

    编程要求

    仔细阅读右侧编辑区内给出的代码框架及注释,按照提示编写程序代码。

    /**
     * 重写 Shape 中的 area 方法,计算球的表面积。
     */
    
    class Shape {
        private double r; //球的半径
        // 球的体积
        public double area(){
            double s = (double)3/4*Math.PI*Math.pow(r,3);
            return s;
        }
    }
    public class Sphere extends Shape{
    
        private double r; //球的半径
        
        public Sphere(double r) {
            this.r = r;
        }
        // 请在下面的Begin-End之间按照注释中给出的提示编写正确的代码
        /********* Begin *********/
        // 重写 Shape 中的 area 方法,计算球的表面积,将计算结果返回
        public double area(){
            double s = (double)4*Math.PI*Math.pow(r,2);
            return s;
        }
        
        public static void main(String []args) {
        	Sphere sphere=new Sphere(2);
        	System.out.println("球的表面积是:"+sphere.area());
        	
        }
        /********** End **********/
    }
    
    
    
    展开全文
  • 西 安 邮 电 大 学 计算机学院 课内实验报告 实验名称 继承与多态 专业名称 计算机科学...Java 语言继承多态特性 掌握变量的隐藏 方法的覆盖 重载掌握抽象类和接口的使用 二实验要求 1.编写体现类的继承性成员变量
  • Java继承与多态(多态篇)

    多人点赞 热门讨论 2022-05-17 10:12:43
    写在前面: 博主主页:戳一戳,欢迎大佬指点! 博主秋秋:QQ:1477649017 欢迎志同道合的...多态一,多态概念二,多态的实现条件2.1,向上转型2.2,重写父类方法2.3,通过父类引用调用重写的方法2.4,整体代码三,向..

    在这里插入图片描述

    🎉🎉🎉写在前面:
    博主主页:🌹🌹🌹戳一戳,欢迎大佬指点!
    博主秋秋:QQ:1477649017 欢迎志同道合的朋友一起加油喔💪
    目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个小菜鸟嘿嘿
    -----------------------------谢谢你这么帅气美丽还给我点赞!比个心-----------------------------

    在这里插入图片描述



    🌈一,多态概念

    多态的概念:多态就是多种形态,意思就是对于同一件事情,如果去完成它的对象不同,最后产生的结果也是不一样的,有不同的状态

    还是拿猫猫和狗狗给大家举个例子,如图:

    在这里插入图片描述


    🌈二,多态的实现条件

    在java里面,对于多态的实现,必须满足一下几个条件:

    🚀1,必须是在继承的条件下,因为涉及到多个子类对象。

    🚀2,子类必须重写父类中的方法。

    🚀3,通过父类的引用调用子类重写的方法。(这里会发生一个向上转型)


    介绍完条件后,那我们要怎么实现多态呢?步骤如下:

    🌟2.1,向上转型

    向上转型就是用父类的引用来接收子类的对象

    class Animal{};
    class Dog extends Animal{};
    //实例化对象的时候如下:
    Animal animal = new Dog();
    

    如这段代码,animal这个父类的引用接收的是子类Dog的对象,这里就是发生了向上转型。但是注意,animal到底是父类的引用,所以这个时候你通过animal能访问到的只是父类自己特有的成员以及方法,不能访问到子类的成员与方法的


    🌟2.2,重写父类方法

    重写,也称覆写或者覆盖,指的是子类对父类中的方法进行重新定义,来实现自己特有的行为

    class Animal{
    ......//省略一些代码,会在后面完全展出
         public void eat(){
            System.out.println(name + "正在吃饭!");
        }
    }
    class Dog extends Animal{
    ......
        public void eat(){//重写父类的方法
            System.out.println(getName() + "正在吃狗粮!");
        }
    }
    

    如这段代码,子类中的eat方法就是对父类中的eat方法进行了重写,从而定义了自己特有的行为功能。


    既然有了这么一个概念,重写的使用也是存在着很多的注意事项的…

    🚩注意:

    🚀1,子类在重写方法的时候,方法的方法名,参数列表,返回值都必须和父类的保持相同。其中,返回值我们是要求相同,但是,如果父类的返回值与子类的返回值也构成父子关系的话,这种情况也是允许的。(协变类型)

    class Animal{
    ......//省略一些代码,会在后面完全展出
         public Animal eat(){
            System.out.println(name + "正在吃饭!");
            return new Animal();
        }
    }
    class Dog extends Animal{
    ......
        @Override
        public Dog eat(){//重写父类的方法
            System.out.println(getName() + "正在吃狗粮!");
            return new Dog();
        }
    }
    

    🚀2,父类中,被static,private,final(final修饰得到称为密封方法)修饰的方法,以及构造方法,都是不能被重写的。

    🚀3,子类方法的访问修饰符的权限必须大于等于父类方法的访问权限。(private < default < protected < public)

    🚀4,在重写的方法前,可以用 @Override注解来进行标识,这样就可以进行一些合法性的校验,例如把方法名写错,编译器就会报错提醒。


    🚩【扩展】重载与重写的对比分析

    在这里插入图片描述

    总的来说,重载只要求名字相同,然后参数列表必须不同,其余随意;重写除了返回值的特殊情况,都必须保持一样。


    🌟2.3,通过父类引用调用重写的方法

    class Animal{
    ......//省略一些代码,会在后面完全展出
         public Animal eat(){
            System.out.println(name + "正在吃饭!");
            return new Animal();
        }
    }
    class Dog extends Animal{
    ......
        @Override
        public Dog eat(){//重写父类的方法
            System.out.println(getName() + "正在吃狗粮!");
            return new Dog();
        }
    }
    public class TestDemo220516 {
        public static void func(Animal animal){//用父类的引用接收子类的对象
            animal.eat();//动态绑定
        }
        public static void main(String[] args) {
            func(new Dog("狗狗",5));//参数是子类的对象
        }
    }
    

    这个时候就完全的实现了多态,其中还有一点需要知道的是这个时候发生了动态绑定,或者说运行时绑定。因为我们上面说过,父类的引用不能调用子类的方法的,但是这里确确实实最后执行的是子类的重写的方法,那到底是为什么呢?

    我们利用 javap -c 文件名 查看了编译时主函数类的字节码文件,如下:

    在这里插入图片描述

    我们可以看到,在编译的时候,func里面显示的还是调用的父类自己的eat方法呀,根本就没有调用子类的重写的方法,但是最后结果又是输出的子类方法的执行结果,难道之前的结论是错误的嘛,其实都没有错,想想之前说的动态绑定(运行时绑定),虽然编译的时候还是显示调用父类的方法,但是运行的时候肯定是绑定调用了子类的重写的方法的。

    在这里插入图片描述


    🚩【动态绑定与静态绑定】

    🚀静态绑定:也称为前期绑定(早绑定),即在编译时,根据用户所传递实参类型就确定了具体调用那个方法。典型代表函数重载。
    🚀动态绑定:也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用那个类的方法。典型代表函数重写。

    🌟2.4,整体代码

    class Animal{
        private String name;
        private int age;
    
        public Animal(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public int getAge() {
            return age;
        }
    
        @Override
        public String toString() {
            return "Animal{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
         public void eat(){
            System.out.println(name + "正在吃饭!");
        }
    }
    class Dog extends Animal{
        private String color;//子类特有属性
    
        public Dog(String name, int age) {
            super(name, age);
        }
        @Override
        public void eat(){//重写父类的方法
            System.out.println(getName() + "正在吃狗粮!");
        }
    }
    
    class Cat extends Animal{
        private String weight;//子类特有属性
    
        public Cat(String name, int age) {
            super(name, age);
        }
        public void eat(){//重写父类的方法
            System.out.println(getName() + "正在吃猫粮!");
        }
    }
    public class TestDemo220516 {
        public static void func(Animal animal){
            animal.eat();
        }
        public static void main(String[] args) {
            func(new Dog("狗狗",5));
            func(new Cat("猫猫",5));
        }
    }
    
    //上面注意一个点,因为父类中的成员都是定义的private的,所以我们子类虽然继承了,对象空间中也确实存在这些成员,但是子类无法直接访问到,所以父类中需要提供公共的接口
    

    程序运行截图:

    在这里插入图片描述


    🌈三,向下转型

    将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法(重写时的动态绑定是个例外),但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换

    class Animal{
        private String name;
        private int age;
    
        public Animal(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public int getAge() {
            return age;
        }
    
        @Override
        public String toString() {
            return "Animal{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
         public void eat(){
            System.out.println(name + "正在吃饭!");
        }
    }
    class Dog extends Animal{
        private String color;//子类特有属性
    
        public Dog(String name, int age) {
            super(name, age);
        }
        @Override
        public void eat(){//重写父类的方法
            System.out.println(getName() + "正在吃狗粮!");
        }
        public void swim(){
            System.out.println(getName() + "在游泳!");
        }
    }
    public class TestDemo220516 {
        public static void main(String[] args) {
            Animal animal = new Dog("狗狗",5);
            Dog dog = (Dog)(animal);//向下转型
            dog.swim();//调用Dog类特有的swim方法
        }
    }
    

    但是呢,虽然有向下转型的方法,我们一般最好也不要用,因为很容易出错。

    public static void main(String[] args) {
            Animal animal = new Cat("猫猫",5);
            Dog dog = (Dog)(animal);
            dog.swim();
        }
    

    编译没有报错,但是运行后会发现:

    在这里插入图片描述

    报出了这么一个异常,表示转换的两边两个类的类型不兼容,为什么,因为这个时候我们的animal引用的是Cat类的对象,然后你要将其强制转换成Dog类的对象,那肯定是行不通的,所以我们必须得改进为如下:

    public static void main(String[] args) {
            Animal animal = new Cat("猫猫",5);
            if(animal instanceof Dog){
                Dog dog = (Dog)(animal);
                dog.swim();
            }
        }
    

    这里引入了instanceof,用来判断前者是不是引用了后者的实例对象,是的话,结果为true,否则为false。这样就避免了上面的错误情况,只有当animal引用的也是Dog类的对象时,才能执行里面的向下转型的代码,也才能用来调用Dog类的方法。

    其实到这里,我们可以发现,向上转型是向下转型的前提,并且只有当我们向上转型时引用的子类的对象类型与我们向下转型时想转型成为的类的类型一样时,才能正确的完成向下转型(或者说之前必须已经引用了这个类)。


    🌈四,多态的优缺点

    优点:

    🚀1, 能够降低代码的 “圈复杂度”。

    🚀2,代码可扩展能力强。

    缺点:

    代码运行效率降低。


    注意:应该避免在构造方法里面调用重写方法

    class Animal{
        private String name;
        private int age;
    
        public Animal(String name, int age) {
            this.name = name;
            this.age = age;
            eat();//构造方法里面调用重写的方法
        }
    
        public String getName() {
            return name;
        }
    
        public int getAge() {
            return age;
        }
    
        @Override
        public String toString() {
            return "Animal{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
         public void eat(){
            System.out.println(name + "正在吃饭!");
        }
    }
    class Dog extends Animal{
        private String color;//子类特有属性
    
        public Dog(String name, int age,String color) {
            super(name, age);
            this.color = color;
        }
        @Override
        public void eat(){//重写父类的方法
            System.out.println(color);
            System.out.println(getName() + "正在吃狗粮!");
        }
        public void swim(){
            System.out.println(getName() + "在游泳!");
        }
    }
    public class TestDemo220516 {
        public static void main(String[] args) {
            Dog dog = new Dog("狗狗",5,"黄色");
        }
    }
    

    程序运行截图:

    在这里插入图片描述

    可以看到,我们new出一个dog对象后,虽然没有直接调用Dog类的eat方法,但是也执行到了,因为在父类的构造方法里面调用了eat,并且还执行的是子类的eat方法,也就是说构造方法里面也会存在动态绑定,这个时候我们在构造子类Dog对象的时候先去调用了父类Animal的构造方法,而里面正好调用了eat方法,所以动态绑定后就直接找到了子类的eat方法。

    但是,这种在构造函数里面调用重写方法极其不推荐,因为很有可能会出问题,因为你在调用子类的重写函数的时候,都还在走父类的构造函数,子类的对象根本就还没构造出来,比如上面的color,我们输出为什么是null,因为在执行Dog的eat方法的时候子类的构造方法都还没执行,其特有属性color也都还没有初始化。


    最后,今天的文章分享比较简单,就到这了,如果大家觉得还不错的话,还请帮忙点点赞咯,十分感谢!🥰🥰🥰
    在这里插入图片描述

    展开全文
  • java 学习笔记——继承,多态,接口继承多态同名异式接口抽象类抽象类 继承 子类会继承父类所有public类型的实例变量和方法,但不会继承父类所有private类型的变量和方法。 继承下来的方法可以被覆盖掉,但实例...

    java 学习笔记——继承,多态,接口

    继承

    • 子类会继承父类所有public类型的实例变量和方法,但不会继承父类所有private类型的变量和方法。

    • 继承下来的方法可以被覆盖掉,但实例变量不能被覆盖掉

    • 可以用IS-A测试来验证继承机构的合理性,IS-A- 关系是单方向的,河马是动物,但动物不一定是河马

    • 当某个方法在子类中被覆盖了,调用这个方法会调用到被覆盖的方法

    • 父类类型的引用 可以调用父类中定义的所有属性和方法,对于子类中定义的而父类中没有的,父类类型的引用不能调用!
      (!!!编译器是通过引用变量的类型来决定那些属性和方法可以被调用,而不是根据引用的对象本身的类型!!!)

    • 使用super关键字引用父类对象,即可以调用父类方法。

    • 参数和返回类型也可以多态

    同名异式

    1. 遵守合约:覆盖的规则
      当你要覆盖父类的方法时,就得同意履约。方法就是合约的规则:
      • 参数必须一样,并且返回类型必须兼容
      • 不能降低方法的存取权限
    2. 方法的重载(overload)
      重载的意义是两个方法名称相同,但参数不同,所以和重载和多态毫无关系。
    • 必须使用不同的参数
    • 返回的类型可以不同
    • 可以任意更改存取权限

    接口与抽象类

    继承只是个开始,要使用多态我们还需要接口。接口是一种100%纯抽象的类
    在这里插入图片描述

    抽象类:是无法被初始化为对象的类,设计抽象类只需要在类的声明前加上abstract
    具体类:是实际可以被初始化为对象的。即抽象类是不能被“new”出一个对象。
    抽象的方法:除了类之外,也可以把方法标为abstract。抽象类代表此类一定被extend过,抽象的方法代表此方法一定被覆盖过。抽象方法没有方法体,直接以分号结束!

    public abstract void eat();
    
    • 如果你声明出一个抽象方法,就必须把类也声明为抽象的。你不能在非抽象类中拥有抽象方法。
    • 抽象方法的意义在于:定义出一组子型的共同协议,而不是实现方法内容,那样跟继承有什么区别(继承使得子类能够继承共同的程序代码)。
      抽象类除了被继承外,是没有用途,没有值,没有目的
    • 可以抽象类型作为引用类型,这也是当初为何要有抽象类型的目的。
    • 继承树结构下的第一个具体的类必须实现出所有的抽象方法。
    • 可以通过抽象机制将实现的负担转移给下层
    • 抽象类可以带有抽象方法和非抽象方法,因此可以部分实现继承的抽象方法,而把剩下的转移给子类。

    Object(对象类)
    Java中所有的类都是从Object这个类中继承出来的。

    • 许多ArrayList的方法都用到Object这个终极类型,因为每个类都是对象的子类,所以ArrayList可以处理任何类。
    • 任何从ArrayList<Object>取出来的东西都被当作Object类型的引用,而不管它原来是什么。这代表你只会取得Object的遥控器。
    • Object类是具体类,Object对象是一个轻量化的对象,常用于线程的同步化。

    接口与多态

    1. 多态
    • 当你定义出一组父型时,你可以用子型的任何类来填补任何需要或期待父型的位置。(因为子类永远可以通过父类引用类型的IS-A测试,而反过来则不行,因为父类的对象不一定就是子类)
    • “多态”意味着“很多形式”。你可以把Snowboard当作是Snowboard或者Object
      在这里插入图片描述
    • 运用多态时,引用类型可以是实际对象的父类
      当你声明一个引用变量时,任何可以通过该引用变量类型的IS-A测试的对象都可以赋值给该引用变量。
    • 转换回原来的类型:让ArrayList<Object>取出来的对象恢复成Dog
    Object o = al.get(index);
    // 1. 如果你真确定该对象是个Dog
    Dog d = (Dog) o;
    d.roam();
    // 2. 如果你不确定该对象是不是Dog
    if(o instanceof Dog){
    	Dog d = (Dog) o;
    	d.roam();
    }
    

    》》》 Java非常重视引用变量的类型,你只能在引用变量的类确有该方法才能调用它《《《

    1. 接口与多态
      Java中不允许多重继承,即只能继承一个父类,否则会有“致命方块”问题。Java的接口是100%的纯抽象类。类可以实现多个接口。
    //接口的定义
    public interface Pet{
    	public abstract void beFriendly();
    }
    // 接口的实现
    public class Dog extends Canine implements Pet{...}
    
    • 当你需要定义一群子类的模板,又不想让程序员初始化此模板时,设计抽象类给它们用
    • 如果想定义类可以扮演的角色,使用接口
    • 可以用接口取代具体的子类或抽象的父类作为参数或返回类型,则你就可以传入任何有实现该接口的东西
    展开全文
  • java之继承与多态

    2018-07-15 15:43:08
    java之继承与多态1、继承子类继承父类的状态和行为可以修改父类的状态或重载父类的行为可以添加新的状态和行为Java支持单继承:一个类只能有父类。Java通过接口(interface)来间接实现多继承。 好处可以提高程序的...
  • Java封装,继承多态详解,带代码示例。
  • java 继承 多态继承与多态是面向对象的语言的两个重要的特点,深入的认识对运用好这门编程语言非常重要。今天的内容包括两部分,概念整理和代码分析。现附上一段今天写的代码,因为对这部分不满意,之后会填坑重写。...
  • java基础之继承与多态

    2020-12-18 22:23:34
    1、继承多态的前提,没有继承就没有多态。 2、继承主要解决的问题是:共性抽取。 3、继承的特点: 1、子类可以拥有父类可继承的内容。 2、子类可以拥有自己专有的内容。 继承关系中,“子类就是一个父类”。...
  • 封装、继承多态三大特征是java中比较常用的,务必要掌握,下面给大家介绍Java封装、继承多态三大特征的理解,有不清楚的朋友可以一起学习下
  • 任务描述 编程要求 测试说明 任务描述 本关任务:计算球的表面积。 编程要求 仔细阅读右侧编辑区内给出的代码框架及注释,按照提示编写程序代码。...平台将使用测试集运行你编写的程序代码,若全部的运行结果正确...
  • java继承多态

    千次阅读 多人点赞 2021-10-08 21:38:20
    继承和多态 文章目录继承和多态继承多态 继承 多态
  • 西 西 安 安邮 邮 电 大 学 (计算机学院)课内实验报告 实验名称::态 继承与...Java 语言继承与多态特性,掌握变量得隐藏、方法得覆盖、重载,掌握抽象类接口得使用。二、实验要求1、编写体现类得继承性(成...
  • 头歌实践--Java面向对象 - 封装、继承多态
  • Java继承与多态

    2021-12-11 15:13:36
    什么是继承继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和方法...Java不支持多继承,但是支持多重继承 继承的特性 1.子类拥有父类非private的成员属性、成员方法(不继承父类的构造方法)
  • 任务描述 编程要求 测试说明 任务描述 本关任务:定义名为 print 的静态方法,携带一个参数,无论该参数是 int 型、double 型还是字符串型,都可以将该参数进行打印。 编程要求 仔细阅读右侧编辑区内给出的代码...
  • java之封装,继承多态

    千次阅读 2022-01-28 17:07:35
    ​ 今天总结一下关于Java的三大特性,封装,继承多态。其实关于三大特性对于从事编程人员来说都是基本的了,毕竟只要接触Java这些都是先要认识的,接下来就系统总结一下。 二,封装 ​ 先来说说特性一:封装 ...
  • 面向对象有三大特性:封装继承与多态。通过简单易于理解的案例和概念,依次学习该三大特性。
  • 主要介绍了Java 继承与多态的深入理解的相关资料,子类继承父类的特征和行为,使得子类具有父类的各种属性和方法。或子类从父类继承方法,使得子类具有父类相同的行为,需要的朋友可以参考下
  • java中的继承多态

    千次阅读 2021-02-28 16:44:33
    1、什么是继承继承的特点?子类继承父类的特征和行为,使得子类具有父类的各种属性和方法。或子类从父类继承方法,使得子类具有父类相同的行为。特点:在继承关系中,父类更通用、子类更具体。父类具有更一般的...
  • 封装继承多态java面向对象中的三大特性,关于这三个特性具体有什么作用,能干什么,我们一起来探讨一下,如有语言形容不清楚,或者表达不准确,欢迎留言。 一、封装 1、封装是什么:官方来讲就是隐藏对象的属性...
  • Java语言程序设计:第四章 继承与多态.ppt
  • 新类可从现有的类中产生,将保留现有类的状态属性和方法并可根据需要加以修改。新类还可添加新的状态属性和方法,这些新增功能允许以统一的风格处理不同类型的数据。这种现象就称为类的继承
  • 主要介绍了Java面向对象编程(封装/继承/多态)实例解析的相关内容,具有一定参考价值,需要的朋友可以了解下。
  • 类的继承还是有点绕的,多用用才行 掌握知识点 super关键字的使用语法 extends的使用语法 类的继承 父类属性和方法的继承 面向对象传参机制 get()和set()方法的使用 public class Dog extends Animal{ //继承...
  • 狗属哺乳动物,且它的属性有品种分(在哺乳类基础上增加品种数据成员),叫声区别于其他动物(输出“Woof!”),还会摇尾巴(增加成员函数,输出“Tail wagging…”),乞讨食物(增加成员函数,输出“begging ...
  • Java继承与多态

    2022-05-26 13:14:18
    2.2.1、基于继承实现的多态 2.2.2、基于接口实现的多态 1、继承 1.1、继承的定义 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,553
精华内容 39,421
关键字:

java语言之继承与多态