zoukankan      html  css  js  c++  java
  • 03Java基础——继承

    1.继承

    例如一个员工类,包括开发员工和经理。

    package cn.jxufe.java.chapter2.demo12;
    
    public class Employee {
        String name;
        
        public void work() {
            System.out.println("员工在工作...");
        }
    }
    package cn.jxufe.java.chapter2.demo12;
    
    /*
     *  定义研发部员工
     *    属于员工中的一种
     *    研发员工继承员工类
     *    
     *    关键字 extends
     *    子类是Developer, 父类是Employee
     *    子类自动拥有父类中可以继承的属性和方法
     *    
     *    子类中,可以直接调用父类的成员
     */
    public class Developer extends Employee {
            
        public void print() {
            System.out.println("the name of Developer is " + name);
        }
        
    }
    package cn.jxufe.java.chapter2.demo12;
    
    public class Manager extends Employee {
        public void printf() {
            System.out.println("the name of Manager is " + name);
        }
    }
    package cn.jxufe.java.chapter2.demo12;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Developer d = new Developer();
            d.name = "开发者";
            d.print();
            
            Manager m = new Manager();
            m.name = "经理";
            m.printf();
            
            d.work();
            m.work();
        }
    
    }

    继承的好处:

    1、继承的出现提高了代码的复用性,提高软件开发效率。

    2、继承的出现让类与类之间产生了关系,提供了多态的前提。

    2.变量的隐藏和方法的覆盖

    2.1变量的隐藏

    package cn.jxufe.java.chapter3.demo2;
    
    public class Student {
        String name = "student";
    }
    package cn.jxufe.java.chapter3.demo2;
    
    public class CollegeStudent extends Student {
        String name = "CollegeStudent";
    
        public void printName() {
            System.out.println("collegeStudent name is " + name);
            System.out.println("student name is " + super.name);
    
        }
    }
    package cn.jxufe.java.chapter3.demo2;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            CollegeStudent collegeStudent = new CollegeStudent();
            System.out.println(collegeStudent.name);
            collegeStudent.printName();
        }
    
    }

    2.2方法的重写

     

    举例:

      比如手机,当描述一个手机时,它具有发短信,打电话,显示来电号码功能,后期由于手机需要在来电显示功能中增加显示姓名和头像,这时可以重新定义一个类描述智能手机,并继承原有描述手机的类。并在新定义的类中覆盖来电显示功能,在其中增加显示姓名和头像功能。

    注意:

    package cn.jxufe.java.chapter3.demo3;
    
    public class Phone {
        
        public void sendMessage() {
            System.out.println("发短信");
        }
    
        public void call() {
            System.out.println("打电话");
        }
    
        public void showNum() {
            System.out.println("来电显示号码");
        }
    }
    package cn.jxufe.java.chapter3.demo3;
    
    //智能手机类
    public class NewPhone extends Phone {
    
        // 覆盖父类的来电显示号码功能,并增加自己的显示姓名和图片功能
        public void showNum() {
            // 调用父类已经存在的功能使用super
            super.showNum();
            // 增加自己特有显示姓名和图片功能
            System.out.println("显示来电姓名");
            System.out.println("显示头像");
        }
    }
    package cn.jxufe.java.chapter3.demo3;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            new NewPhone().showNum();
        }
    }

    3.super关键字

    3.1调用父类的构造方法

    package cn.jxufe.java.chapter3.demo4;
    
    public class Person {
        String color;
        String language;
    
        public Person(String color, String language) {
            // TODO Auto-generated constructor stub
            this.color = color;
            this.language = language;
        }
    
    }
    package cn.jxufe.java.chapter3.demo4;
    
    public class ChinesePerson extends Person {
        int age;
        // String color;
        // String language; 注意子类中不要再重新定义这两个属性了,否则出错
    
        public ChinesePerson(String color, String language, int age) {
            // TODO Auto-generated constructor stub
            super(color, language);
            this.age = age;
    
        }
    }
    package cn.jxufe.java.chapter3.demo4;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            ChinesePerson chinesePerson = new ChinesePerson("yellow", "chinese", 20);
    
            System.out.println(chinesePerson.color);
            System.out.println(chinesePerson.age);
        }
    
    }

    3.2调用父类的方法(用于重写了父类的方法)

     2.2中已经应用。

    4.抽象类和抽象方法 

    4.1抽象类和抽象方法的产生

      当编写一个类时,我们往往会为该类定义一些方法,这些方法是用来描述该类的功能具体实现方式,那么这些方法都有具体的方法体。

    但是有的时候,某个父类只是知道子类应该包含怎么样的方法,但是无法准确知道子类如何实现这些方法。比如一个图形类应该有一个求周长的方法,但是不同的图形求周长的算法不一样。那该怎么办呢?

    分析事物时,发现了共性内容,就出现向上抽取。会有这样一种特殊情况,就是方法功能声明相同,但方法功能主体不同。那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。那么此方法就是一个抽象方法。

     

    4.2抽象类和抽象方法的定义

    /*
     抽象方法定义的格式:
        public abstract 返回值类型 方法名(参数);
        
    抽象类定义的格式:
        abstract class 类名 {
        }
    
     */
    package cn.jxufe.java.chapter3.demo5;
    
    /*
     *  定义类开发工程师类
     *    EE开发工程师 :  工作
     *    python开发工程师 : 工作
     *    
     *    根据共性进行抽取,然后形成一个父类Developer
     *    定义方法,工作: 怎么工作,具体干什么呀
     *    
     *    抽象类,不能实例化对象, 不能new的
     *    不能创建对象的原因:  如果真的让你new了, 对象.调用抽象方法,抽象方法没有主体,根本就不能运行
     *    抽象类使用: 定义类继承抽象类,将抽象方法进行重写,创建子类的对象
     */
    public abstract class Developer {
        
        public abstract void work();
    
    }
    package cn.jxufe.java.chapter3.demo5;
    
    public class JavaEE extends Developer {
        public void work() {
            System.out.println("JavaEE工程师在工作...");
        }
    }
    package cn.jxufe.java.chapter3.demo5;
    
    public class Python extends Developer {
        public void work() {
            System.out.println("Python工程师在工作...");
        }
    }
    package cn.jxufe.java.chapter3.demo5;
    
    /*
     *  测试抽象类
     *    创建他的子类的对象,使用子类的对象调用方法
     */
    public class Test {
        public static void main(String[] args) {
            JavaEE ee = new JavaEE();
            ee.work();
    
            Python py = new Python();
            py.work();
        }
    }

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

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

     2. 抽象关键字abstract不可以和哪些关键字共存?

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

    2、final,暂时不关注,后面学

    3、static,暂时不关注,后面学

    5.抽象类案例简单应用

    5.1案例描述

      某IT公司有多名员工,按照员工负责的工作不同,进行了部门的划分(研发部员工、维护部员工)。研发部根据所需研发的内容不同,又分为JavaEE工程师、Android工程师;维护部根据所需维护的内容不同,又分为网络维护工程师、硬件维护工程师。

      公司的每名员工都有他们自己的员工编号、姓名,并要做它们所负责的工作。

         工作内容:

    • JavaEE工程师:员工号为xxx的 xxx员工,正在研发淘宝网站
    • Android工程师:员工号为xxx的 xxx员工,正在研发淘宝手机客户端软件
    • 网络维护工程师:员工号为xxx的 xxx员工,正在检查网络是否畅通
    • 硬件维护工程师:员工号为xxx的 xxx员工,正在修复打印机

      请根据描述,完成员工体系中所有类的定义,并指定类之间的继承关系。进行XX工程师类的对象创建,完成工作方法的调用。

    5.2案例分析

    5.3案例实现

    package cn.jxufe.java.chapter3.demo6;
    
    public abstract class Employee {
        private String id;// 员工编号
        private String name; // 员工姓名
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        // 工作方法(抽象方法)
        public abstract void work();
    
    }
    package cn.jxufe.java.chapter3.demo6;
    
    // 定义研发部员工类Developer 继承 员工类Employee
    public abstract class Developer extends Employee {
        
    }
    package cn.jxufe.java.chapter3.demo6;
    
    public abstract class Maintainer extends Employee{
    
    }
    package cn.jxufe.java.chapter3.demo6;
    
    public class JavaEE extends Developer {
        @Override
        public void work() {
            System.out.println("员工号为 " + getId() + " 的" + getName() + "员工,正在研发淘宝网站");
    
        }
    }
    package cn.jxufe.java.chapter3.demo6;
    
    public class Android extends Developer {
        @Override
        public void work() {
            System.out.println("员工号为 " + getId() + " 的 " + getName() + " 员工,正在研发淘宝手机客户端软件");
        }
    }
    package cn.jxufe.java.chapter3.demo6;
    
    public class Hardware extends Maintainer {
        @Override
        public void work() {
            System.out.println("员工号为 " + getId() + " 的 " + getName() + " 员工,正在修复打印机");
        }
    }
    package cn.jxufe.java.chapter3.demo6;
    
    public class Network extends Maintainer {
        @Override
        public void work() {
            System.out.println("员工号为 " + getId() + " 的 " + getName() + " 员工,正在检查网络是否畅通");
        }
    }
    package cn.jxufe.java.chapter3.demo6;
    
    public class Test {
        public static void main(String[] args) {
            // 创建JavaEE工程师员工对象
            JavaEE ee = new JavaEE();
            // 设置该员工的编号
            ee.setId("000015");
            // 设置该员工的姓名
            ee.setName("小明");
            // 调用该员工的工作方法
            ee.work();
        }
    }

    6.接口

    6.1接口的概念

    6.2接口的定义

    例子:

      狗的叫声是“汪汪汪”,猫的叫声是“喵喵喵”,羊的叫声是“咩咩咩”。将动物中叫这种行为定义为对外接口。

    package cn.jxufe.java.chapter3.demo7;
    
    public interface Shout {
        void shoutSound(); // 和public abstract void shoutSound() 等价
    }

    6.3接口的实现 

    package cn.jxufe.java.chapter3.demo7;
    
    public class Dog implements Shout {
        
        public void shoutSound() {
            // TODO Auto-generated method stub
            System.out.println("狗的叫声是“汪汪汪”");
        }
    }
    package cn.jxufe.java.chapter3.demo7;
    
    public class Cat implements Shout {
        
        public void shoutSound() {
            // TODO Auto-generated method stub
            System.out.println("猫的叫声是“喵喵喵”");
        }
    
    }
    package cn.jxufe.java.chapter3.demo7;
    
    public class Sheep implements Shout {
        // @Override 注意不是重写这个功能,而是实现,加这个将报错
        public void shoutSound() {
            // TODO Auto-generated method stub
            System.out.println("羊的叫声是“咩咩咩”");
        }
    
    }
    package cn.jxufe.java.chapter3.demo7;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            new Dog().shoutSound();
            new Cat().shoutSound();
            new Sheep().shoutSound();
        }
    
    }

    6.4Comparable接口

    package cn.jxufe.java.chapter3.demo7;
    
    import java.util.Date;
    
    public class TestComparable {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            System.out.println(new Integer(3).compareTo(new Integer(5)));
            System.out.println("ABC".compareTo("ABE"));
            System.out.println("ABC".compareTo("ABF"));
    
            Date date1 = new Date(2013, 1, 1);
            Date date2 = new Date(2012, 1, 1);
            System.out.println(date1.compareTo(date2));
        }
    
    }

    package cn.jxufe.java.chapter3.demo7;
    
    import java.math.BigInteger;
    import java.util.Arrays;
    
    public class TestSortComparable {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            String[] cities = { "nanchang", "beijing", "shanghai", "xuzhou", "nanjing" };
            Arrays.sort(cities);
            for (String city : cities)
                System.out.print(city + " ");
            System.out.println();
    
            BigInteger[] hugeNumbers = { new BigInteger("232323199305142015"), new BigInteger("323199305142015"),
                    new BigInteger("45213549679215") };
            Arrays.sort(hugeNumbers);
            for (BigInteger number : hugeNumbers)
                System.out.print(number + " ");
        }
    }

    package cn.jxufe.java.chapter3.demo7;
    
    import java.util.Arrays;
    
    public class TestComparableRectangle implements Comparable<TestComparableRectangle> {
        double height;
        double width;
    
        public TestComparableRectangle(double height, double width) {
            // TODO Auto-generated constructor stub
            this.height = height;
            this.width = width;
        }
    
        public double getArea() {
            return height * width;
        }
    
        @Override
        public int compareTo(TestComparableRectangle o) {
            // TODO Auto-generated method stub
            if (getArea() > o.getArea())
                return 1;
            else if (getArea() < o.getArea())
                return -1;
            else
                return 0;
    
        }
    
        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return "with: " + width + " height " + height + " Area: " + getArea();
        }
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            TestComparableRectangle[] rectangles = { new TestComparableRectangle(3.4, 5.4),
                    new TestComparableRectangle(13.24, 55.4), new TestComparableRectangle(7.4, 35.4),
                    new TestComparableRectangle(1.4, 22.4) };
            Arrays.sort(rectangles);
            for (TestComparableRectangle rectangle : rectangles)
                System.out.println(rectangle);
        }
    }

    6.5Comparator接口

    package cn.jxufe.java.chapter3.demo7;
    
    import java.util.Comparator;
    
    public class GeometricObjectComparator implements Comparator<GeometricObject> {
    
        @Override
        public int compare(GeometricObject o1, GeometricObject o2) {
            // TODO Auto-generated method stub
            double area1 = o1.getArea();
            double area2 = o2.getArea();
            if (area1 < area2)
                return -1;
            else if (area1 == area2)
                return 0;
            else
                return 1;
        }
    
        public static void main(String[] args) {
            GeometricObject g1 = new Rectangle(5, 5);
            GeometricObject g2 = new Circle(5);
    
            GeometricObject g = max(g1, g2, new GeometricObjectComparator());
            System.out.println("the area of the larger object is " + g.getArea());
        }
    
        public static GeometricObject max(GeometricObject g1, GeometricObject g2, Comparator<GeometricObject> c) {
            if (c.compare(g1, g2) > 0)
                return g1;
            else
                return g2;
        }
    }

    7.接口的应用小例子

    package cn.jxufe.java.chapter3.demo8;
    
    public interface Ishape {
        double PI = 3.14159; // 和public static final double PI = 3.14159等价
    
        double getArea(); // 和public abstract double getArea()等价
    
        double getPerimeter();
    
    }
    package cn.jxufe.java.chapter3.demo8;
    
    public class Circle implements Ishape {
        double redius;
    
        public Circle(double redius) {
            // TODO Auto-generated constructor stub
            this.redius = redius;
        }
    
        public double getArea() {
            return redius * redius * PI;
        }
    
        public double getPerimeter() {
            return 2 * redius * PI;
        }
    
    }
    package cn.jxufe.java.chapter3.demo8;
    
    public class Rectangle implements Ishape {
        double height;
        double wight;
    
        public Rectangle(double height, double wight) {
            // TODO Auto-generated constructor stub
            this.height = height;
            this.wight = wight;
        }
    
        public double getArea() {//必须用public权限
            return height * wight;
        }
    
        public double getPerimeter() {
            return 2 * (height + wight);
        }
    }
    package cn.jxufe.java.chapter3.demo8;
    
    public class Triangle implements Ishape {
        double a, b, c;
    
        public Triangle(double a, double b, double c) {
            // TODO Auto-generated constructor stub
            this.a = a;
            this.b = b;
            this.c = c;
        }
    
        public double getArea() {
            double s = 0.5 * (a + b + c);
            return Math.sqrt(s * (s - a) * (s - b) * (s - c));
        }
    
        public double getPerimeter() {
            return a + b + c;
        }
    
    }
    package cn.jxufe.java.chapter3.demo8;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Circle circle = new Circle(10);
            System.out.println("circle area is " + circle.getArea() + " circle perimeter is " + circle.getPerimeter());
    
            Rectangle rectangle = new Rectangle(10, 20);
            System.out.println(
                    "Rectangle area is " + rectangle.getArea() + " rectangle perimeter is " + rectangle.getPerimeter());
    
            Triangle triangle = new Triangle(3, 4, 5);
            System.out.println(
                    "triangle area is " + triangle.getArea() + " triangle perimeter is " + triangle.getPerimeter());
    
        }
    }

    8.接口的多实现

    package cn.jxufe.java.chapter3.demo9;
    
    public interface A {
        public abstract void a();
    
        public abstract void b();
    
    }
    package cn.jxufe.java.chapter3.demo9;
    
    public interface B {
        public abstract void a();
    }
    package cn.jxufe.java.chapter3.demo9;
    
    public class C implements A,B{
        public  void a() {
            System.out.println("print a");
        }
        
        public void b() {
            // TODO Auto-generated method stub
            System.out.println("pringt b");
        }
    }
    package cn.jxufe.java.chapter3.demo9;
    
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            C c = new C();
            c.a();
            c.b();
        }
    
    }

    9. 类继承类同时实现接口

    接口和类之间可以通过实现产生关系,同时也学习了类与类之间可以通过继承产生关系。当一个类已经继承了一个父类,它又需要扩展额外的功能,这时接口就派上用场了。

    子类通过继承父类扩展功能,通过继承扩展的功能都是子类应该具备的基础功能。如果子类想要继续扩展其他类中的功能呢?这时通过实现接口来完成。

    class Fu {
        public void show(){}
    }
    interface Inter {
        pulbic abstract void show1();
    }
    class Zi extends Fu implements Inter {
        public void show1() {
        }
    }

    接口的出现避免了单继承的局限性。父类中定义的事物的基本功能。接口中定义的事物的扩展功能。

    10. 接口的多继承

    学习类的时候,知道类与类之间可以通过继承产生关系,接口和类之间可以通过实现产生关系,那么接口与接口之间会有什么关系。

    多个接口之间可以使用extends进行继承。

    interface Fu1{
        void show();
    }
    interface Fu2{
        void show1();
    }
    interface Fu3{
        void show2();
    }
    interface Zi extends Fu1,Fu2,Fu3{
        void show3();
    }

    在开发中如果多个接口中存在相同方法,这时若有个类实现了这些接口,那么就要实现接口中的方法,由于接口中的方法是抽象方法,子类实现后也不会发生调用的不确定性。

    11.接口的思想

      前面学习了接口的代码体现,现在来学习接口的思想,接下里从生活中的例子进行说明。

    举例:

      我们都知道电脑上留有很多个插口,而这些插口可以插入相应的设备,这些设备为什么能插在上面呢?主要原因是这些设备在生产的时候符合了这个插口的使用规则,否则将无法插入接口中,更无法使用。发现这个插口的出现让我们使用更多的设备。

    总结:接口在开发中的它好处

    1、接口的出现扩展了功能。

    2、接口其实就是暴漏出来的规则。

    3、接口的出现降低了耦合性,即设备与设备之间实现了解耦。

    接口的出现方便后期使用和维护,一方是在使用接口(如电脑),一方在实现接口(插在插口上的设备)。例如:笔记本使用这个规则(接口),电脑外围设备实现这个规则(接口)。

  • 相关阅读:
    [转]给C++初学者的50个忠告
    [转]代理模式——代理模式的核心思想
    [转]单例模式——C++实现自动释放单例类的实例
    [转]代理模式——何时使用代理模式
    观察者模式——生动的气象信息订阅服务图示
    [转]单例模式——Java中互斥访问单一实例
    [转]C++ const变量使用技巧总结
    [转]用C++设计一个不能被继承的类
    ExtJs2.0学习系列(14)Ext.TreePanel之第三式(可增删改的树)
    ExtJs2.0学习系列(7)Ext.FormPanel之第四式(其他组件示例篇)
  • 原文地址:https://www.cnblogs.com/xinmomoyan/p/10903860.html
Copyright © 2011-2022 走看看