Java学习笔记2

下面程序结果

Demo2_Student静态代码块
我是main方法
Student 静态代码块
Student 构造代码块
Student 构造方法
Student 构造代码块
Student 构造方法

class Student {
    static {
        System.out.println("Student 静态代码块");
    }
    
    {
        System.out.println("Student 构造代码块");
    }
    
    public Student() {
        System.out.println("Student 构造方法");
    }
}

class Demo2_Student {
    static {
        System.out.println("Demo2_Student静态代码块");
    }
    
    public static void main(String[] args) {
        System.out.println("我是main方法");
        
        Student s1 = new Student();
        Student s2 = new Student();
    }
}

继承案例演示

  • A:继承(extends)
    • 让类与类之间产生关系,子父类关系
  • B:继承案例演示:
    • 动物类,猫类,狗类
    • 定义两个属性(颜色,腿的个数)两个功能(吃饭,睡觉)
  • C:案例演示
    • 使用继承前
  • D:案例演示
    • 使用继承后
class Demo1_Extends {
    public static void main(String[] args) {
        Cat c = new Cat();
        c.color = "red";
        c.leg = 4;
        c.eat();
        c.sleep();
    }
}

class Animal {
    String color;   //动物的颜色
    int leg;        //动物腿的个数

    public void eat() {    //吃饭的功能
        System.out.println("吃饭");
    }

    public void sleep(){   //睡觉的功能
        System.out.println("睡觉");
    }
}

class Cat extends Animal {}

class Dog extends Animal {}
/*
extends是继承的意思
Animal是父类
Cat和Dog都是子类
*/

继承的好处和弊端

  • A:继承的好处
    • a:提高了代码的复用性
    • b:提高了代码的维护性
    • c:让类与类之间产生了关系,是多态的前提
  • B:继承的弊端
    • 类的耦合性增强了。

    • 开发的原则:高内聚,低耦合。

    • 耦合:类与类的关系

    • 内聚:就是自己完成某件事情的能力

Java中类的继承特点

  • A:Java中类的继承特点
    • a:Java只支持单继承,不支持多继承。(一个儿子只能有一个爹)
      • 有些语言是支持多继承,格式:extends 类1,类2,...
    • b:Java支持多层继承(继承体系)
  • B:案例演示
    • Java中类的继承特点
      • 如果想用这个体系的所有功能用最底层的类创建对象
      • 如果想看这个体系的共性功能,看最顶层的类
class Demo2_Extends {
    public static void main(String[] args) {
        DemoC d = new DemoC();
        d.show();
    }
}

class DemoA {
    public void show() {
        System.out.println("DemoA");
    }
}

class DemoB {
    public void show() {
        System.out.println("DemoA");
    }
}

class DemoC extends DemoA,DemoB {
}
/*
Demo2_Extends.java:20: 错误: 需要'{'
class DemoC extends DemoA, DemoB {
                         ^
*/

继承的注意事项和什么时候使用继承

  • A:继承的注意事项

    • a:子类只能继承父类所有非私有的成员(成员方法和成员变量)
    • b:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法。
    • c:不要为了部分功能而去继承
    • 项目经理 姓名 工号 工资 奖金
    • 程序员 姓名 工号 工资
  • B:什么时候使用继承

    • 继承其实体现的是一种关系:"is a"。
      Person
      Student
      Teacher
      水果
      苹果
      香蕉
      橘子

    采用假设法。
    如果有两个类A,B。只有他们符合A是B的一种,或者B是A的一种,就可以考虑使用继承。

继承中成员变量的关系

  • A:案例演示
    • a:不同名的变量
    • b:同名的变量
class Demo4_Extends {
    public static void main(String[] args) {
        Son s = new Son();
        s.print();
    }
}

class Father {
    int num1 = 10;
    int num2 = 30;
}

class Son extends Father {
    int num2 = 20;

    public void print() {
        System.out.println(num1);  //10
        System.out.println(num2);  //就近原则,子类有就不用父类的了
    }
}
//子父类出现同名的变量只是在讲课中举例子有,在开发中是不会出现这种情况的
//子类继承父类就是为了使用父类的成员,那么如果定义了同名的成员变量就没有意义了

this和super的区别和应用

  • A:this和super都代表什么
    • this:代表当前对象的引用,谁来调用我,我就代表谁
    • super:代表当前对象父类的引用
  • B:this和super的使用区别
    • a:调用成员变量
      • this.成员变量 调用本类的成员变量,也可以调用父类的成员变量(本类没有的情况下)
      • super.成员变量 调用父类的成员变量
    • b:调用构造方法
      • this(...) 调用本类的构造方法
      • super(...) 调用父类的构造方法
    • c:调用成员方法
      • this.成员方法 调用本类的成员方法,也可以调用父类的方法
      • super.成员方法 调用父类的成员方法

继承中构造方法的关系

  • A:案例演示
    • 子类中所有的构造方法默认都会访问父类中空参数的构造方法
  • B:为什么呢?
    • 因为子类会继承父类中的数据,可能还会使用父类的数据。

    • 所以,子类初始化之前,一定要先完成父类数据的初始化。

    • 其实:

      • 每一个构造方法的第一条语句默认都是:super() Object类最顶层的父类
class Demo5_extends {
    public static void main(String[] args) {
        Son s = new Son();
    }
}

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

class Son extends Father {
    public Son() {
        super();    //这是一条语句,如果不写,系统会默认加上,用来访问父类的空参构造
        System.out.println("Son的构造方法");
    }
}
class Demo6_Extends {
    public static void main(String[] args) {
        Son s1 = new Son();
        Son s2 = new Son("张三",23);
    }
}

class Father {
    private String name;
    private int age;
    
    public Father() {
        System.out.println("Father 空参构造");
    }
    
    public Father(String name,int age) {
        this.name = name;
        this.age = age;
        System.out.println("Father 有参构造");
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }
}

class Son extends Father {
    public Son() {                        //空参构造
        super();                          //这是一条语句,如果不写,系统会默认加上,用来访问父类的空参构
        System.out.println("Son 空参构造");
    }

    public Son(String name,int age) {     //有参构造
        super();                          //这是一条语句,如果不写,系统会默认加上,用来访问父类的空参构
        System.out.println("Son 有参构造");
    }
}

继承中构造方法的注意事项

  • A:案例演示
    • 父类没有无参构造方法,子类怎么办?
    • super解决
    • this解决
  • B:注意事项
    • super(…)或者this(….)必须出现在构造方法的第一条语句上,所以这两者不能共存。
class Demo6_Extends {
    public static void main(String[] args) {
        Son s1 = new Son();
        System.out.println(s1.getName() + "..." + s1.getAge());
        Son s2 = new Son("张三",23);
        System.out.println(s2.getName() + "..." + s2.getAge());
    }
}

class Father {
    private String name;
    private int age;
    
    /*public Father() {
        System.out.println("Father 空参构造");
    }*/
    
    public Father(String name,int age) {
        this.name = name;
        this.age = age;
        System.out.println("Father 有参构造");
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }
}

class Son extends Father {
    public Son() {                        //空参构造
        //super("李四",24);                         //调用父类中的构造方法
        this("王五",25);                        //调用本类中的构造方法
        System.out.println("Son 空参构造");
    }

    public Son(String name,int age) {     //有参构造
        super(name,age);                          
        System.out.println("Son 有参构造");
    }
}

继承的例子

class Demo6_Extends {
    public static void main(String[] args) {
        Zi z = new Zi();
    }
    /*
    1,jvm调用了main方法,main进栈
    2,遇到Zi z = new Zi();会先将Fu.class和Zi.class分别加载进内存,再创建对象,当Fu.class
    加载进内存,父类的静态代码块会随着Fu.class一起加载,当Zi.class加载进内存,子类的静态
    代码块会随着Zi.class一起加载,第一个输出静态代码块Fu,第二个输出静态代码块Zi
    3,走Zi类的构造方法,因为java中是分层初始化的,先初始化父类,再初始化子类,所以先走的
    父类构造,但是再执行父类构造时,发现父类有构造代码块,构造代码块是优先于构造方法执行的
    所以第三个输出构造代码块Fu,第四个输出构造方法Fu
    4,Fu类初始化结束,子类初始化,第五个输出的是构造代码块Zi,构造方法Zi
    */
}

class Fu {
    static {
        System.out.println("静态代码块Fu");
    }

    {
        System.out.println("构造代码块Fu");
    }

    public Fu() {
        System.out.println("构造方法Fu");
    }
}

class Zi extends Fu {
    static {
        System.out.println("静态代码块Zi");
    }

    {
        System.out.println("构造代码块Zi");
    }

    public Zi() {
        System.out.println("构造方法Zi");
    }
}

继承中成员方法关系

  • A:案例演示
    • a:不同名的方法
    • b:同名的方法

方法重写概述及其应用

  • A:什么是方法重写
    • 重写:子父类出现了一模一样的方法(注意:返回值类型可以是子父类,这个我们学完面向对象讲)
  • B:方法重写的应用:
    • 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。这样,即沿袭了父类的功能,又定义了子类特有的内容。
class Demo7_Extends {
    public static void main(String[] args) {
        Son s = new Son();
        s.print();
        s.method();
    }
}

class Father {
    public void print() {
        System.out.println("Fu print");
    }
}

class Son extends Father {
    public void method() {
        System.out.println("Zi method");
    }

    public void print() {
        super.print();         //super可以调用父类的成员方法
        System.out.println("Zi print");
    }
}

方法重写的注意事项

  • A:方法重写注意事项
    • a:父类中私有方法不能被重写

      • 因为父类私有方法子类根本就无法继承
    • b:子类重写父类方法时,访问权限不能更低

      • 最好就一致
    • c:父类静态方法,子类也必须通过静态方法进行重写 (若子类是静态方法呢?)

      • 其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解(静态只能覆盖静态,其实不算重写,多态时候详细讲解)
    • 子类重写父类方法的时候,最好声明一模一样。

  • B:案例演示
    • 方法重写注意事项

方法重写的面试题

  • A:方法重写的面试题
    • Override和Overload的区别?Overload能改变返回值类型吗?

    • overload可以改变返回值类型,只看参数列表,与返回值类型无关

    • 方法重写:子类中出现了和父类中方法声明一模一样的方法。与返回值类型有关,返回值是一致(或者是子父类)的

    • 方法重载:本类中出现的方法名一样,参数列表不同的方法。与返回值类型无关。

    • 子类对象调用方法的时候:

      • 先找子类本身,再找父类。

实例

class Test4_Person {
    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("张三");
        s1.setAge(23);
        System.out.println(s1.getName() + "..." + s1.getAge());
        s1.eat();
        s1.study();

        Student s2 = new Student("李四",24);
        System.out.println(s2.getName() + "..." + s2.getAge());
        s1.eat();
        s1.study();
    }
}

class Person {
    private String name;
    private int age;

    public Person() {}

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void eat() {
        System.out.println(name + "吃饭");
    }

    
}

class Student extends Person {
    public Student() {}   //空参构造

    public Student(String name,int age) {
        super(name,age);
    }

    public void study() {
        System.out.println(super.getName() + "学习");  //这里super.getName()和this.getName()都可以,一个是直接访问一个是继承,但是效果一致。
    }
}

class Teacher extends Person {
    public Teacher() {}   //空参构造

    public Teacher(String name,int age) {
        super(name,age);
    }

    public void teach() {
        System.out.println(getName() + "教书");  //getName()等效于this.getName()
    }
}

final关键字修饰类,方法以及变量的特点

  • A:final概述
  • B:final修饰特点
    • 修饰类,类不能被继承
    • 修饰变量,变量就变成了常量,只能被赋值一次
    • 修饰方法,方法不能被重写

final关键字修饰局部变量

  • A:案例演示
    • 方法内部或者方法声明上都演示一下(了解)

    • 基本类型,是值不能被改变

    • 引用类型,是地址值不能被改变,对象中的属性可以改变

class Demo2_Final {
    public static void main(String[] args) {
        final int NUM = 10;
        //NUM = 20;
        System.out.println(NUM);

        final Person p = new Person("张三",23);
        //p = new Person("李四",24);
        p.setName("李四");
        p.setAge(24);

        System.out.println(p.getName() + "..." + p.getAge());

        method(10);   
        method(20);   //不会报错,因为上面方法调用完后会弹栈
    }

    public static void method(final int x) {
        System.out.println(x);
    }
}

class Person {
    private String name;
    private int age;
    
    public Person() {}

    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }
}

final修饰变量的初始化时机

  • A:final修饰变量的初始化时机
    • 显示初始化
    • 在对象构造完毕前即可
class Demo3_Final {
    public static void main(String[] args) {
        Demo d = new Demo();
        d.print();
    }
}

class Demo {
    //final int NUM = 10;   //1.显示初始化 
    //final int NUM   //成员变量的默认初始化值是无效值
    final int NUM;          //2.在对象构造中初始化
    public Demo() {
        NUM = 10;
    }

    public void print() {
        System.out.println(NUM);
    }
}

多态的概述及其代码体现

  • A:多态(polymorphic)概述
    • 事物存在的多种形态
  • B:多态前提
    • a:要有继承关系。
    • b:要有方法重写。
    • c:要有父类引用指向子类对象。
class Demo1_Polymorphic {
    public static void main(String[] args) {
        Cat c = new Cat();
        c.eat();

        Animal a = new Cat();                //父类引用指向子类对象
        a.eat();
    }
}

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

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

多态中的成员访问特点之成员变量和成员方法

  • 成员变量
    • 编译看左边(父类),运行看左边(父类)。
  • 成员方法
    • 编译看左边(父类)(确保父类中有这个方法),运行看右边(子类)。(动态绑定)
class Demo2_Polymorphic {
    public static void main(String[] args) {
        Father f1 = new Son();                //父类引用指向子类对象
        System.out.println(f1.num);

        Son s = new Son();
        System.out.println(s.num);

        Father f2 = new Son();
        f2.print();
    }
}

class Father {
    int num = 10;

    public void print() {
        System.out.println("father");
    }
}

class Son extends Father {
    int num = 20;

    public void print() {
        System.out.println("son");
    }
}
多态中的成员变量.png

多态中的成员方法.png

多态中的成员访问特点之静态成员方法

  • 静态方法
    • 编译看左边(父类),运行看左边(父类)。
    • (静态和类相关,算不上重写,所以,访问还是左边的)
    • 只有非静态的成员方法,编译看左边,运行看右边
class Demo2_Polymorphic {
    public static void main(String[] args) {
        Father f1 = new Son();                //父类引用指向子类对象
        System.out.println(f1.num);

        Son s = new Son();
        System.out.println(s.num);

        Father f2 = new Son();
        f2.print();
        f2.method();              //相当于是Father.method()
    }
}

class Father {
    int num = 10;

    public void print() {
        System.out.println("father");
    }

    public static void method() {
        System.out.println("father static method");
    }
}

class Son extends Father {
    int num = 20;

    public void print() {
        System.out.println("son");
    }

    public static void methog() {
        System.out.println("son static method");
    }
}

多态中向上转型和向下转型

  • A:案例演示
    • 详细讲解多态中向上转型和向下转型
      Person p = new SuperMan();向上转型
      SuperMan sm = (SuperMan)p;向下转型
class Demo3_superMan {
    public static void main(String[] args) {
        Person p = new SuperMan();           //父类引用指向子类对象,超人提升为了人
        System.out.println(p.name);          //父类引用指向子类对象就是向上转型
        p.business();
        SuperMan sm = (SuperMan) p;            //向下转型
        sm.fly();
    }
}

class Person {
    String name = "John";

    public void business() {
        System.out.println("谈生意");
    }
}

class SuperMan extends Person {
    String name = "superMan";

    public void business() {
        System.out.println("谈几个亿的大单子");
    }

    public void fly() {
        System.out.println("飞出去救人");
    }
}
向上和向下转型.jpg

多态的好处和弊端

  • A:多态的好处
    • a:提高了代码的维护性(继承保证)
    • b:提高了代码的扩展性(由多态保证)
  • B:案例演示
    • 多态的好处
    • 可以当作形式参数,可以接收任意子类对象
  • C:多态的弊端
    • 不能使用子类的特有属性和行为。
class Demo4_Animal {
    public static void main(String[] args) {
        method(new Cat());
        method(new Dog());

        //Animal a = new Cat();    开发的时候很少在创建对象的时候用父类引用指向子类对象,直接创建子类对象更方便,可以使用子类中的特有属性和行为
    }
    
    //如果把狗强转成猫就会出现类型转换异常,ClassCastException
    public static void method(Animal a) {    //当作参数的时候用多态最好,因为扩展性强
        //Cat c = (Cat)a;
        //关键字 instanceof 判断前边的引用是否是后边的数据类型
        if (a instanceof Cat) {
            Cat c = (Cat)a;
            c.eat();
            c.catchMouse();
        }else if (a instanceof Dog) {
            Dog d = (Dog)a;
            d.eat();
            d.lookHome();
        }else {
            a.eat();
        }
    }
}

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

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

    public void catchMouse() {
        System.out.println("抓老鼠");
    }
}

class Dog extends Animal {
    public void eat() {
        System.out.println("狗吃肉");
    }

    public void lookHome() {
        System.out.println("看家");
    }
}

多态中的题目分析题

  • 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 Test1Demo {
          public static void main(String[] args) {
              Fu f = new Zi();
              f.method();
              f.show();
          }
      }
    
  • 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 Test2DuoTai {
          public static void main(String[] args) {
              A a = new B();
              a.show();
              
              B b = new C();
              b.show();
          }
      }
    

自己的猜测:结果分析,继承相当于是将父类的代码拷贝到子类,所以是先看子类有没有此方法,没有在看父类有没有这个方法,如果有运行结果等价于(将代码拷贝到子类运行)

抽象类的概述及其特点

  • A:抽象类概述
    • 抽象就是看不懂的
  • B:抽象类特点
    • a:抽象类和抽象方法必须用abstract关键字修饰
      • abstract class 类名 {}
      • public abstract void eat();
    • b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口
    • c:抽象类不能实例化那么,抽象类如何实例化呢?
      • 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
    • d:抽象类的子类
      • 要么是抽象类
      • 要么重写抽象类中的所有抽象方法
  • C:案例演示
    • 抽象类特点B:抽象类特点
    • a:抽象类和抽象方法必须用abstract关键字修饰
      • abstract class 类名 {}
      • public abstract void eat();
    • b:抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或者是接口
    • c:抽象类不能实例化那么,抽象类如何实例化呢?
      • 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
    • d:抽象类的子类
      • 要么是抽象类
      • 要么重写抽象类中的所有抽象方法
class Demo1_Abstract {
    public static void main(String[] args) {
        //Animal a = new Animal();//错误: Animal是抽象的; 无法实例化
        Animal a = new Cat();     //抽象类实例化,父类引用指向子类对象
        a.eat();
    }
}

abstract class Animal {              //抽象类
    public abstract void eat();      //抽象方法
}

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

抽象类的成员特点

  • A:抽象类的成员特点
    • a:成员变量:既可以是变量,也可以是常量。abstract是否可以修饰成员变量?不能修饰成员变量
    • b:构造方法:有。
      • 用于子类访问父类数据的初始化。
    • c:成员方法:既可以是抽象的,也可以是非抽象的。
  • B:案例演示
    • 抽象类的成员特点
  • C:抽象类的成员方法特性:
    • a:抽象方法 强制要求子类做的事情。
    • b:非抽象方法 子类继承的事情,提高代码复用性。
class Demo2_Abstract {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

abstract class Demo {
    int num1 = 10;
    final int NUM2 = 20;

    public Demo(){}

    public void print() {
        System.out.println("111");
    }

    public abstract void method();
}

class Test extends Demo {
    public void method() {
        System.out.println("111");
    }
}

抽象类练习猫狗案例

class Test1_Animal {
    public static void main(String[] args) {
        Cat c = new Cat("加菲",8);
        System.out.println(c.getName() + "..." + c.getAge());
        c.eat();
        c.catchMouse();

        Dog d = new Dog("八公",30);
        System.out.println(d.getName() + "..." + d.getAge());
        d.eat();
        d.lookHome();
    }
}

abstract class Animal {
    private String name;
    private int age;

    public Animal(){}    //空参

    public Animal(String name,int age) {  //有参
        this.name = name;
        this.age = age;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public abstract void eat();

}

class Cat extends Animal {
    public Cat(){}    //空参

    public Cat(String name,int age) {  //有参
        super(name,age);
    }

    public void eat() {
        System.out.println("猫吃鱼");
    }

    public void catchMouse() {
        System.out.println("抓老鼠");
    }
}
class Dog extends Animal {
    public Dog(){}    //空参

    public Dog(String name,int age) {  //有参
        super(name,age);
    }

    public void eat() {
        System.out.println("狗吃肉");
    }

    public void lookHome() {
        System.out.println("看家");
    }
}

抽象类练习员工案例

  • A:案例演示
    • 假如我们在开发一个系统时需要对程序员类进行设计,程序员包含3个属性:姓名、工号以及工资。
    • 经理,除了含有程序员的属性外,另为还有一个奖金属性。
    • 请使用继承的思想设计出程序员类和经理类。要求类中提供必要的方法进行属性访问。
class Test3_Employee {
    public static void main(String[] args) {
        Coder c = new Coder("德玛西亚","007",8000);
        c.work();

        Manager m = new Manager("苍老师","9527",3000,20000);
        m.work();
    }
}

abstract class Employee {
    private String name;
    private String id;
    private double salary;

    public Employee() {}

    public Employee(String name,String id,double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }
    
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public String getId() {
        return id;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }

    public abstract void work();
}

class Coder extends Employee {
    public Coder() {}

    public Coder(String name,String id,double salary) {
        super(name,id,salary);
    }

    public void work() {
        System.out.println(this.getName() + this.getId() + this.getSalary() + "敲代码");
    }
}

class Manager extends Employee {
    private int bonus;      //奖金

    public Manager() {}

    public Manager(String name,String id,double salary,int bonus) {
        super(name,id,salary);
        this.bonus = bonus;

    }

    public void work() {
        System.out.println(this.getName() + this.getId() + this.getSalary() + bonus +"管理");
    }
}

抽象类中的面试题

  • A:面试题1
    • 一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
    • 可以
    • 这么做目的只有一个,就是不让其他类创建本类对象,交给子类完成
  • B:面试题2
    • abstract不能和哪些关键字共存
      abstract和static
      被abstrac修饰的方法没有方法体
      被static修饰的可以用类名.调用,但是类名.调用抽象方法是没有意义的
      abstract和final
      被abstract修饰的方法强制子类重写
      被final修饰的不让子类重写,所以矛盾
      abstract和private
      被abstract修饰的是为了让子类看到并强制重写
      被private修饰不让子类访问,所以矛盾
class Demo4_Abstract {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

abstract class Demo {
    //public static abstract void print();//错误: 非法的修饰符组合: abstract和static
    //public final abstract void print();//错误: 非法的修饰符组合: abstract和final
    //private abstract void print();//错误: 非法的修饰符组合: abstract和private
}

接口的概述及其特点

A:接口概述
* 从狭义的角度讲就是指java中的interface
* 从广义的角度讲对外提供规则的都是接口

  • B:接口特点
    • a:接口用关键字interface表示
      • interface 接口名 {}
    • b:类实现接口用implements表示
      • class 类名 implements 接口名 {}
    • c:接口不能实例化
      • 那么,接口如何实例化呢?
      • 按照多态的方式来实例化。
    • d:接口的子类
      • a:可以是抽象类。但是意义不大。
      • b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)

接口的成员特点

A:接口成员特点
* 成员变量;只能是常量,并且是静态的并公共的。
* 默认修饰符:public static final
* 建议:自己手动给出。
* 构造方法:接口没有构造方法。
* 成员方法:只能是抽象方法。
* 默认修饰符:public abstract
* 建议:自己手动给出。

class Demo2_Interface {
    public static void main(String[] args) {
        Demo d = new Demo();
        d.print();
        System.out.println(Inter.num);
    }
}

interface Inter {
    public static final int num = 10;  //public static和final如果不加,系统会默认加上,顺序可以交换
    //public Inter(){}   //接口中没有构造方法

    /*public void print() {    //接口中不能定义非抽象方法
        
    } */ 
    public abstract void print();                //public和abstract如果不加,系统会默认加上
}

class Demo /*extends Object*/ implements Inter {  //一个类不写继承任何类,默认继承Object类
    public void print() {
        System.out.println(num);
    }
}

类与类,类与接口,接口与接口的关系

  • A:类与类,类与接口,接口与接口的关系
    • a:类与类:
      • 继承关系,只能单继承,可以多层继承。
    • b:类与接口:
      • 实现关系,可以单实现,也可以多实现。
      • 并且还可以在继承一个类的同时实现多个接口。
    • c:接口与接口:
      • 继承关系,可以单继承,也可以多继承。
class Demo3_Interface {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

interface InterA {
    public abstract void printA();
}

interface InterB {
    public abstract void printB();
}

interface InterC extends InterB,InterA {
}

class Demo extends Object implements InterA,InterB {
    public void printA() {
        System.out.println("printA");
    }

    public void printB() {
        System.out.println("printB");
    }
}

抽象类和接口的区别

  • A:成员区别

    • 抽象类:
      • 成员变量:可以变量,也可以常量
      • 构造方法:有
      • 成员方法:可以抽象,也可以非抽象
    • 接口:
      • 成员变量:只可以常量
      • 成员方法:只可以抽象
  • B:关系区别

    • 类与类
      • 继承,单继承
    • 类与接口
      • 实现,单实现,多实现
    • 接口与接口
      • 继承,单继承,多继承
  • C:设计理念区别

    • 抽象类 被继承体现的是:”is a”的关系。抽象类中定义的是该继承体系的共性功能。
    • 接口 被实现体现的是:”like a”的关系。接口中定义的是该继承体系的扩展功能。

猫狗案例加入跳高功能分析及其代码实现

class Test1_Animals {
    public static void main(String[] args) {
        Cat c = new Cat("加菲",8);
        c.eat();
        c.sleep();

        JumpCat jc = new JumpCat("跳高猫",3);
        jc.eat();
        jc.sleep();
        jc.jump();
    }
}

abstract class Animal {
    private String name;
    private int age;

    public Animal() {}       //空参构造

    public Animal(String name,int age) {  //有参构造
        this.name = name;
        this.age = age;
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public abstract void eat();

    public abstract void sleep();
}

interface Jumping {
    public void jump();
}

class Cat extends Animal {
    public Cat() {}

    public Cat(String name,int age) {
        super(name,age);
    }

    public void eat() {
        System.out.println("猫吃鱼");
    }

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

class JumpCat extends Cat implements Jumping {
    public JumpCat() {}

    public JumpCat(String name,int age) {
        super(name,age);
    }
    public void jump() {
        System.out.println("猫跳高");
    }
}

你可能感兴趣的:(Java学习笔记2)