zoukankan      html  css  js  c++  java
  • 【07】Java入门07:继承与抽象类

    一、继承

    1.继承

      在程序中,如果想声明一个类继承另一个类,需要使用extends关键字。

    class 子类 extends 父类 {}

    2.继承

     package day03;
    /*
     * 继承:多个类有共同的成员变量和成员方法,抽取到另外一个类中(父类),在让多个类去继承这个父类,我们的多个类就可以获取到父类中的成员了。
     * extends
     * 
     */
    public class ExtendsDemo {
        public static void main(String[] args) {
            DotA1 d = new DotA1();
            d.start();
           
            LOL1 l = new LOL1();
            l.start();
        }
    }
     
    class Game1 {
        String name;
        double version;//版本号
        String agent;//代理商
       
        public void start() {
            System.out.println("游戏启动了");
        }
       
        public void stop() {
            System.out.println("游戏关闭了");
        }
    }
     
    class DotA1 extends Game1 {
        /*String name;
        double version;//版本号
        String agent;//代理商
        
        public void start() {
            System.out.println("游戏启动了");
        }
        
        public void stop() {
            System.out.println("游戏关闭了");
        }*/
    }
     
    class LOL1 extends Game1 {
        /*String name;
        double version;//版本号
        String agent;//代理商
        
        public void start() {
            System.out.println("游戏启动了");
        }
        
        public void stop() {
            System.out.println("游戏关闭了");
        }*/
       
    }

    3.继承的特点

      ①在Java中,类只支持单继承,不允许多继承,也就是说一个类只能有一个直接父类,例如下面这种情况是不合法的。

    class A{} 
        class B{}
        class C extends A,B{}  // C类不可以同时继承A类和B类

      ②多个类可以继承一个父类,例如下面这种情况是允许的。

    class A{}
    class B extends A{}
    class C extends A{}   // 类B和类C都可以继承类A

      ③在Java中,多层继承是可以的,即一个类的父类可以再去继承另外的父类,例如C类继承自B类,而B类又可以去继承A类,这时,C类也可称作A类的子类。下面这种情况是允许的。

    class A{}
    class B extends A{}   // 类B继承类A,类B是类A的子类
    class C extends B{}   // 类C继承类B,类C是类B的子类,同时也是类A的子类

      ④在Java中,子类和父类是一种相对概念,也就是说一个类是某个类父类的同时,也可以是另一个类的子类。例如上面的这种情况中,B类是A类的子类,同时又是C类的父类。

    4.继承中成员变量的特点

        1) 子类只能获取父类非私有成员

            ①子父类中成员变量的名字不一样直接获取父类的成员变量。
            ②子父类中成员变量名字是一样的获取的是子类的成员变量。

        2) 就近原则

            ①谁离我近我就用谁。
            ②如果有局部变量就使用局部变量。
            ③如果没有局部变量,有子类的成员变量就使用子类的成员变量。
            ④如果没有局部变量和子类的成员变量,有父类的成员变量就使用父类的成员变量。
        3) super

            ①可以获取父类的成员变量和成员方法,用法和this是相似的。

    public class ExtendsDemo3 {
        public static void main(String[] args) {
            Kid3 k = new Kid3();
            k.show();
        }
    }
     
    class Dad3 {
        String name = "建霖";
    }
     
    class Kid3 extends Dad3 {
        String name = "四葱";
       
        public void show() {
            String name = "五葱";
           
            System.out.println(super.name);
            System.out.println(this.name);
            System.out.println(name);
        }
    }

    5.继承中成员方法的特点

      ①子类中没有这个方法,调用父类的。
      ②子类中重写了这个方法,调用子类的。

    6.方法的重写

      在子父类当中,子类的方法和父类的完全一样,子类重写了父类的方法(覆盖),当子类重写了父类的方法之后,使用子类对象调用的就是子类的方法。

    7.方法的重载

      在一个类中,有多个重名的方法,但是其参数不一样(参数的个数,参数的类型,参数的顺序),和返回值无关。

    public class ExtendsDemo4 {
        public static void main(String[] args) {
            Kid4 k = new Kid4();
            k.eat();
        }
    }
     
    class Dad4 {
        public void eat() {
            System.out.println("小酌两口");
            System.out.println("去睡觉了");
        }
    }
     
    class Kid4 extends Dad4 {
        public void eat() {
            System.out.println("好好吃饭");
        }
    }

    8.方法重写的应用场景 & 注意事项

        1) 方法重写的应用场景

            当父类的方法不能完全满足子类使用的时候,既可以保留父类的功能(沿袭、传承),还可以有自己特有的功能。

        2) 方法重写的注意事项
            不可以重写父类私有的成员方法,压根就看不到父类的私有成员。
            子类重写父类方法,权限必须大于等于父类方法的权限。

        3) 注解
            @Override:方法重写,说明下面的方法是重写父类的方法。

    public class ExtendsDemo5 {
        public static void main(String[] args) {
            NewPhone np = new NewPhone();
            np.call();
        }
    }
     
    class Phone {
        void call() {
            System.out.println("打电话");
        }
    }
     
    class NewPhone extends Phone {
       
        @Override
        public void call() {
            System.out.println("录音");
            //System.out.println("打电话");
           
            //super.call();
        }
    }

    9.继承中构造方法的执行顺序

      ①super(实参列表):在子类的构造方法中使用,用来调用父类中的构造方法(具体哪一个由传递的参数决定),并且只能在构造方法第一行使用。
      ②this(实参列表);:在类的构造方法中使用,用来调用本类中的其它构造方法(具体哪一个由传递的参数决定),并且只能在构造方法的第一行使用。

    10.this和super的区别

        1) this:当前对象的引用

            ①调用子类的成员变量。
            ②调用子类的成员方法。
            ③在子类的构造方法第一行调用子类其他构造方法。

        2) super:子类对象的父类引用

            ①调用父类的成员变量。
            ②调用父类的成员方法。
            ③在子类的构造方法第一行调用父类的构造方法。

    11.继承优缺点

        1) 优点

            ①提高了代码的复用性。
            ②提高了代码的可维护性。

        2) 缺点

            类的耦合性增强了。

        3) 开发的原则

            高内聚低耦合。
        4) 内聚

            就是自己完成某件事情的能力。
        5) 耦合

            类与类的关系。

    二、抽象类

    1.抽象类概述

      当编写一个类时,我们往往会为该类定义一些方法,这些方法是用来描述该类的功能具体实现方式,那么这些方法都有具体的方法体。但是有的时候,某个父类只是知道子类应该包含怎么样的方法,但是无法准确知道子类如何实现这些方法。比如一个图形类应该有一个求周长的方法,但是不同的图形求周长的算法不一样。
      分析事物时,发现了共性内容,就出现向上抽取。会有这样一种特殊情况,就是方法功能声明相同,但方法功能主体不同。那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。

    /*
     * abstract:关键字,用于修饰方法和类
     * 抽象方法:不同类的方法是相似,但是具体内容又不太一样,所以我们只能抽取他的声明,没有具体的方法体,没有具体方法体的方法就是抽象方法
     * 抽象类:有抽象方法的类必须是抽象类
     * 
     * 注意:一个类继承了抽象类需要重写他所有的抽象方法,否则这个类就得是抽象类
     */
    public class AbstractDemo {
     
    }
     
    abstract class Animal1 {
        public abstract void eat();
       
        //非抽象方法子类可以不重写
        public void run() {
           
        }
    }
     
    class Cat1 extends Animal1 {
     
        @Override
        public void eat() {
            System.out.println("猫吃鱼");
           
        }
       
        /*public void eat() {
            System.out.println("猫吃鱼");
        }*/
    }
     
    abstract class Dog1 extends Animal1 {
        /*public void eat() {
            System.out.println("狗吃屎");
        }*/
    }

    2.抽象类的特点

      ①抽象方法只能在抽象类里面。
      ②抽象类和抽象方法必须被abstract修饰。
      ③抽象类不能创建对象(不能实例化)。
      ④抽象类中可以有非抽象的方法。
      ⑤抽象类和类的关系也是继承。
      ⑥一个类继承了抽象类要么重写所有的抽象方法,要么他自己是抽象类。

    3.抽象类成员的特点

        1) 成员变量

            ①可以有成员变量。
            ②可以有常量。

        2) 成员方法

            ①可以有抽象方法。
            ②可以有非抽象方法。

        3) 构造方法
              ①可以有构造方法的,需要对抽象类的成员变量进行初始化。

    4.抽象类案例

    package day06;
    /*
     * 	程序员: 姓名,工号,薪水,工作内容
     * 	项目经理: 姓名,工号,薪水,工作内容,奖金
     * 
     * 	属性:name,id,pay
     * 	行为:work
     */
    public class abstractTest2 {
        public static void main(String[] args) {
            Programmer p = new Programmer();
            p.work();
    		
            Manager m = new Manager();
            m.work();
        }
    }
    
    abstract class Employee {
        String name;
        String id;
        double pay;
    
        public abstract void work();
    }
    
    class Programmer extends Employee{
        
        @Override
        public void work() {
            System.out.println("写代码");
        }
    }
    
    class Manager extends Employee{
        byte bonus;
    	
        @Override
        public void work() {
            System.out.println("盯着程序员写代码");
        }
    }

    5.abstract可与哪些关键字共存?

        1) private

            私有的方法子类是无法继承到的,也不存在覆盖,而abstract和private一起使用修饰方法,abstract既要子类去实现这个方法,而private修饰子类根本无法得到父类这个方法。互相矛盾。
        2) final

            抽象类不能和final共存,因为抽象类自身无法创建对象,我们需要通过子类创建对象,一旦抽象类使用final关键字,那么抽象类就没有子类。
            抽象方法不能和final共存,因为抽象方法后期需要被子类重写,一旦加final无法重写。

        3) static
            抽象方法不能和static关键字共存,因为一旦加static我们就可以通过类名直接访问抽象方法,由于抽象方法没有方法体,没有任何意义,也不允许这样做。

    6.抽象类中是否可以不定义抽象方法?

      是可以的,那这个抽象类的存在到底有什么意义呢?不让该类创建对象,方法可以直接让子类去使用。

    7.抽象类是否有构造函数?

      有,抽象类的构造函数,是由子类的super语句来调用,用于给抽象类中的成员初始化。

  • 相关阅读:
    Android仿人人客户端(v5.7.1)——个人主页(三)
    hdu2554-N对数的排列问题
    POJ1363:Rails
    golang printf
    HDU1200:To and Fro
    [C# 基础知识系列]专题六:泛型基础篇——为什么引入泛型
    poj 2480 (欧拉函数应用)
    Re:从0开始的微服务架构--(二)快速快速体验微服务架构?--转
    爬虫推荐的工具
    python2 与 python3 语法区别--转
  • 原文地址:https://www.cnblogs.com/djcoder/p/13264136.html
Copyright © 2011-2022 走看看