面向对象3

继承

继承后类和类之间关系的说法

class A extends B{} A类是B类的一种, 谁是谁的一种

class Student extends Person

class Teacher extends Person

class Object类,所有类都继承Object

继承后子类和父类之间的成员变量特点

  • 成员变量特点 : 如果子类自己有,就是使用自己的,如果自己没有使用父类继承
  • 方法中调用本类的成员 this.调用
  • 要是调用父类的成员 ,关键字super.调用

super关键字

在继承中, super关键字用来调用父类的成员, 子类中调用自己的成员是this,调用父类的成员是super

super : 表示父类的内存中的存储位置

super内存图.jpg

继承后子类和父类之间成员方法特点

当子类中出现了和父类一模一样的方法, 这样的现象称为子类重写父类的方法.

  • 方法的重写(override) :
    • 方法的重载(overload),同一个类中,方法名一样,参数列表不同
    • 方法的重写(override),子类中的方法和父类的方法一样 (方法的声明一样)
  • 允许特点 : 如果子类重写了父类的方法(子类自己有),运行子类的.如果子类没有,运行父类继承的
  • 方法重写的注意事项
    • 重写的时候,子类方法的权限必须大于或者等于父类方法的权限 public protected default private
    • 父类的方法是private修饰的,但是私有修饰的成员,子类不知道父类有这个成员,继承不过来,因此就不存在重写的问题

方法重写的案例

继承的本身含义,为了扩展,为了延伸

方法重写案例.jpg
/*
 *  早年的移动电话
 *  打电话,发信息,来电
 */
public class Phone {
    public void call() {
        System.out.println("手机拨号打电话");
    }
    
    public void sendMessage() {
        System.out.println("手机发信息");
    }
    
    public void receive() {
        System.out.println("响铃");
        System.out.println("显示姓名和号码");
    }
}
/*
 * 新的智能手机
 *   继续使用原有手机的功能  继承
 *   扩展自己的新功能  方法重写
 */
public class IPhone extends Phone{
    //扩展自己的新功能  方法重写
    //重写来电方法
    public void receive() {
        /*
         * 响铃,显示姓名和号码 
         * 父类的方法已经实现了
         * 直接使用父类已经做好的方法!!
         */
            super.receive();
        System.out.println("显示大头像");
        System.out.println("显示归属地");
        System.out.println("显示推销");
    }
}

继承后子类和父类之间构造方法特点

特点 : 子类的构造方法,第一行有一个默认的隐式的代码, super()

不写super(),也会存在的 javac编译器帮你写

super() 作用,调用父类的无参数构造方法!!

子类构造方法第一行super().jpg

无论子类重载多少个构造方法,第一行默认的语句都是 super()

如果父类中,没有无参数的构造方法

子类的构造方法中,我们自己要手写一个super(传递参数)

如果父类中,有多个构造方法. 子类的构造方法,任意的调用一个即可

this()和super()

  • this访问本类成员
  • super调用父类成员
  • 确定 : 构造方法第一行代码,默认的是super()
  • this()和super() 在构造方法中,都要站在第一行,不能同时出现,只能选择一个
  • 写this()的构造方法,会通过其他的构造方法,间接调用到父类构造方法
this()和super()问题.jpg

抽象类

抽象概念 : 凡是说不清的,讲不明白的就是抽象

抽象类由来 : 继承思想,是子类的共性内容,抽取形成父类.有些功能在父类中无法具体表现了.

抽象类和抽象方法定义

  • 抽象方法定义 : 关键字 abstract
    • 修饰符 (权限 抽象) 返回值类 方法名(参数列表);
    • 抽象方法没有方法体 {} 不存在的
    • 方法定义分号结束
  • 抽象的方法,必须存在于抽象的类中,因此这个类也要抽象修饰
/*
 *  动物类 :
 *    定义动物的行为 ,吃饭行为 (方法)
 *    动物吃什么,这个细节根本就说不清楚
 */
public abstract class Animal {
    public abstract void eat() ;
}

抽象类的使用

  • 抽象类不能实例化对象,不能new对象
    • 抽象类不能创建对象的原因,方法是抽象的,调用没有意义
  • 需要定义子类继承抽象类
  • 子类必须要重写抽象方法 (override)
    • 去掉抽象修饰符和分号,添加{}方法体
  • 创建子类的对象
/*
 *  Cat猫类,属于动物的一种,继承Animal
 */
public class Cat extends Animal{
    /*
     * 重写父类的抽象方法 eat()
     */
    public void eat() {
        System.out.println("猫吃猫粮");
    }
}

抽象类中成员的定义

  • 抽象类中能否定义非抽象的方法 (普通方法) 能
    • 调用方法,只能依靠子类对象
  • 抽象类中可以定义成员变量吗,可以
    • 变量是私有修饰,提供get set方法访问变量 (get / set 方法使用子类对象调用)
  • 抽象类中可以有构造方法吗, 抽象类也是类,必须有构造方法
  • 抽象类中,可以不定义抽象方法吗,类中的方法全部都是普通方法
    • 虽然没有抽象方法,但是依然是抽象类,不能创建对象
public abstract class Animal {
    
    public Animal() {
        super();
    }
    private int age;
    
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public abstract void eat();
    
    //抽象类中能否定义非抽象的方法 (普通方法)
    public void sleep() {
        System.out.println("动物睡觉::");
    }
}

抽象类的子类依然有可能还是抽象类

当一个子类继承抽象类后,重写了一部分抽象方法,另一部分抽象方法没有重写,子类还是一个抽象类,依然不能建立对象

public abstract class Animal {
    public abstract void eat();
    public abstract void sleep();
}
/*
 * 继承父类Animal,重写了一部分抽象方法
 * 
 * sleep()方法没有重写
 */
public abstract class Cat extends Animal{
    public  void eat() {
    }
    //public abstract void sleep();
}

抽象类存在的意义

抽象类存在的意义.jpg

抽象类的案例

抽象类的员工案例 : 公司的组织

  • 事务分析
    • 财务部员工 : 姓名,工号. 行为 工作
    • 研发部员工 : 姓名,工号. 行为 工作
  • 事务之间存在共性, 抽取 (向上抽取) 形成父类
员工案例分析图.jpg
/*
 *  公司类,共性内容 姓名,工号,工作行为
 */
public abstract class Company {
    private String name; //姓名
    
    private String id; // 工号
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public abstract void work(); // 工作行为
}
/*
 *  研发部员工,属于公司一种继承
 */
public class Development extends Company{

    public void work() {
        System.out.println("研发部的员工在研发芯片");
    }
    
}
/*
 * 财务部员工,是公司的一种 ,继承
 */
public class Finance extends Company{
    public void work() {
        System.out.println("财务部员工在数钱");
    }
}

public static void main(String[] args) {
        //创建研发部对象
        Development d1 = new Development();
        //父类方法 get / set
        d1.setName("张三");
        d1.setId("研发部001");
        System.out.println(d1.getName());
        System.out.println(d1.getId());
        //调用子类重写的work方法
        d1.work();
        
        Development d2 = new Development();
        d2.setName("李四");
        d2.setId("研发部002");
        System.out.println(d2.getName());
        System.out.println(d2.getId());
        d2.work();
        
        Finance f1 = new Finance();
        f1.setName("翠花");
        f1.setId("财务部001");
        System.out.println(f1.getName());
        System.out.println(f1.getId());
        f1.work();
        
        Finance f2 = new Finance();
        f2.setName("翠花plus");
        f2.setId("财务部002");
        System.out.println(f2.getName());
        System.out.println(f2.getId());
        f2.work();
    }

案例改进

public void work() {
        System.out.println("研发部的员工在研发芯片  " + super.getName() +".."+super.getId());
    }
public static void main(String[] args) {
        //创建研发部对象
        Development d1 = new Development();
        //父类方法 get / set
        d1.setName("张三");
        d1.setId("研发部001");
        //调用子类重写的work方法
        d1.work();
        
        Development d2 = new Development();
        d2.setName("李四");
        d2.setId("研发部002");
        d2.work();
        
        Finance f1 = new Finance();
        f1.setName("翠花");
        f1.setId("财务部001");
        f1.work();
        
        Finance f2 = new Finance();
        f2.setName("翠花plus");
        f2.setId("财务部002");
        f2.work();
    }

接口

接口在生活中到处都是, 笔记本USB接口,电源接口

接口 : 在程序中可以这样理解, 当一个类中所有的方法全部是抽象方法的时候,这个类称为接口.

接口是一种特殊的抽象类

接口定义关键字 interface

格式 :

public interface 接口名{
}

接口成员定义 (基于JDK7)

  • JDK7 和 JDK8不一样
  • 成员变量
    • 接口中定义成员变量,固定格式,定义修饰符是固定写法
    • public static final 数据类型 变量名 = 值;
    • 修饰符,写和不写,没有区别,不写不代表没有
  • 成员方法
    • 接口中的成员方法,固定格式
    • public abstract 返回值类型 方法名(参数列表);
/*
 *   MyInterface名字,接口名
 *   修改关键字
 *   接口的源文件名.java, 编译后还是.class文件
 */
public interface MyInterface {
    //定义接口的成员变量
    //public static final 数据类型 变量名 = 值;
    //final最终的,不可改变, 看成常量
    //命名规范 : 常量名字全大写
    public static final  int A = 1;
    
    //定义接口的成员方法
    public abstract void inter();
}

接口的使用

  • 接口的使用方式 :
    • 接口不能实例化对象,不能new
    • 定义类实现接口 (继承父类,改为实现接口)
    • 实现接口关键字 implements
    • 类重写接口的全部抽象方法
    • 创建对象使用
public interface MyInterface {
    public static final int A = 1;
    public abstract void inter();
}
/*
 * 定义类,实现接口
 * 关键字 implements
 * 
 * MyInterfaceImpl类实现了接口MyInterface
 * MyInterfaceImpl类称为接口MyInterface的实现类  (就是子类)
 */

public class MyInterfaceImpl implements MyInterface{
    public void inter() {
        System.out.println("实现类实现接口重写方法");
    }
}
public static void main(String[] args) {
    //创建接口MyInterface的实现类对象
    MyInterfaceImpl my = new MyInterfaceImpl();
    //实现类对象调用方法, 实现类重写方法
    my.inter();
}

接口的多实现

类之间是单继承关系,存在局限性.出现接口概念,可以让一个类实现多个接口, 对单继承的一种技术上的改进.

没有多继承的安全问题,可以多实现

多实现的写法 :

public class A implements 接口B, 接口C{

}
接口多实现.jpg
public interface InterfaceB {
    public abstract void interB();
}
public interface InterfaceC {
    public abstract void interC();
}
/*
 * 做接口的多实现,同时实现接口B和C
 * 必须重写接口B和C的全部抽象方法
 */
public class A implements InterfaceB,InterfaceC{
    public void interB() {
        System.out.println("实现类A重写接口B的方法");
    }
    
    public void interC() {
        System.out.println("实现类A重写接口C的方法");
    }
}
    public static void main(String[] args) {
        //创建对象, 接口B和C的实现类 ,A类对象
        A a = new A();
        
        a.interB();
        a.interC();
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。