美文网首页
Java学习笔记2

Java学习笔记2

作者: 海洋_5ad4 | 来源:发表于2018-10-26 14:37 被阅读0次

    下面程序结果

    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

          本文链接:https://www.haomeiwen.com/subject/exoktqtx.html