(二)、Java复习笔记之面向对象

13、数组的初始化

  • 一维数组:

    • int[] arr = new int[]{1,2,3,4,5}; //正确
    • int[] arr = {1,2,3,4,5}; //正确
    • int[] arr = new int[5]{1,2,3,4,5}; //错误
    • int[] arr;
    • arr = new int[]{1,2,3,4,5}; //正确。
    • arr = {1,2,3,4,5}; //错误
  • 二维数组:

    • int[][] arr = new int[3][2]; //正确
    • int[] arr[] = new int[3][2]; //正确
    • int arr[][] = new int[3][2]; //正确

14、值传递和引用传递

  • 值传递:传递的是值的拷贝,不改变原值。如基本数据类型及其包装类、String。
  • 引用传递:传递的是引用的地址值,改变原值。如类类型,接口类型和数组。
  • Java中只有传值,因为地址值也是值。(面试)

15、static关键字

  • static关键字的特点
    • 随着类的加载而加载
    • 优先于对象存在
    • 被类的所有对象共享
    • 可以通过类名调用
  • static的注意事项
    • 在静态方法中是没有this关键字的
      • 如何理解呢?
        • 静态是随着类的加载而加载,this是随着对象的创建而存在。
        • 静态比对象先存在。
    • 静态方法只能访问静态的成员变量和静态的成员方法
      • 简单记:
        • 静态只能访问静态。
  • 如果一个类中所有的方法都是静态的(工具类),需要私有化构造方法,目的是不让其他类创建本类对象。

16、代码块的概述和分类(面试)

  • 代码块概述
    • 在Java中,使用{}括起来的代码被称为代码块。
  • 代码块分类
    • 根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程)。
  • 常见代码块的应用
    • 局部代码块
      • 在方法中出现;限定变量生命周期,及早释放,提高内存利用率
    • 构造代码块 (初始化块)
      • 在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
    • 静态代码块
      • 在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。
      • 一般用于加载驱动
  • 面试题:看程序写结果

    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();
        }
    }
    结果:
    Demo2_Student静态代码块
    我是main方法
    Student 静态代码块
    Student 构造代码块
    Student 构造方法
    Student 构造代码块
    Student 构造方法
    

17、开发的原则

  • 高内聚,低耦合
  • 耦合:类与类的关系
  • 内聚:就是自己完成某件事情的能力

18、继承的注意事项

  • 子类只能继承父类所有非私有的成员(成员方法和成员变量)
  • 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造方法。
  • 子类中所有的构造方法默认都会访问父类中空参数的构造方法
    • 因为子类会继承父类中的数据,可能还会使用父类的数据。
    • 所以,子类初始化之前,一定要先完成父类数据的初始化。
    • 其实:每一个构造方法的第一条语句默认都是:super(),Object类是最顶层的父类。
  • 当类没有重载有参数的构造方法,JVM会默认增加一个空参数的构造方法。否则,不增加。
  • 面试题

    看程序写结果1:
    class Fu{
        public int num = 10;
        public Fu(){
            System.out.println("fu");
        }
    }
    class Zi extends Fu{
        public int num = 20;
        public Zi(){
            System.out.println("zi");
        }
        public void show(){
            int num = 30;
            System.out.println(num);
            System.out.println(this.num);
            System.out.println(super.num);
        }
    }
    class Test1_Extends {
        public static void main(String[] args) {
            Zi z = new Zi();
            z.show();
        }
    }   
    结果:
    fu
    zi
    30
    20
    10
    
    看程序写结果2
    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");
        }
    }
    
    public class Demo{
        public static void main(String[] args) {
            Zi z = new Zi();
        }
    }
    /*
     * 1、JVM先加载Fu.class,加载后执行Fu静态代码块,然后再加载Zi.class,加载后执行Zi静态代码块。
     * 2、在执行Zi.class的构造方法之前先执行Fu.class的构造方法
     * 3、执行构造方法之前先执行构造代码块
     */
    结果:
    静态代码块Fu
    静态代码块Zi
    构造代码块Fu
    构造方法Fu
    构造代码块Zi
    构造方法Zi
    

19、this和super的区别

  • this和super都代表什么
    • this:代表当前对象的引用,谁来调用我,我就代表谁
    • super:代表当前对象父类的引用
  • this和super的使用区别
    • 调用成员变量
      • this.成员变量 调用本类的成员变量,也可以调用父类的成员变量
      • super.成员变量 调用父类的成员变量
    • 调用构造方法
      • this(…) 调用本类的构造方法
      • super(…) 调用父类的构造方法
    • 调用成员方法
      • this.成员方法 调用本类的成员方法,也可以调用父类的方法
      • super.成员方法 调用父类的成员方法
  • 注意,super(…)或者this(….)必须出现在构造方法的第一条语句上

20、方法重载、方法覆盖、多态

  • 方法重载(Overload):方法名相同,参数不同。

    void foo(String str);
    void foo(int number);
    
  • 方法覆盖(Override):也叫方法重写,父类与子类有同样的方法名和参数。

    class Parent {
        void foo() {
            System.out.println("Parent foo()");
        }
    }
    class Child extends Parent {
        void foo() {
            System.out.println("Child foo()");
        }
    }
    
  • 多态:见下21

21、多态

  • 概述
    • 事物存在多种形态
  • 多态的前提:

    • 要有继承关系
    • 要有方法重写(覆盖)
    • 要有父类引用指向子类对象(调用方法时会调用子类的实现,而不是父类的实现)

      Parent instance = new Child();
      instance.foo(); // Child foo()
      
  • 多态中成员访问特点

    • 成员变量:调用变量时会调用父类的变量
    • 成员方法:调用方法时会调用子类的实现
    • 静态方法:调用方法时会调用父类的实现(静态与类相关,算不上重写)

      public class Demo{
          public static void main(String[] args) {
              Father f = new Son();
              System.out.println(f.num);
              f.print();
              f.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 method(){
              System.out.println("son static method");
          }
      }
      结果:
      10
      son
      father static method
      
  • 多态的好处
    • 提高了代码的维护性(继承保证)
    • 提高了代码的扩展性(由多态保证)
      • 可以作为形式参数,接受任意子类对象
  • 多态的弊端
    • 不能使用子类特有的属性和行为

22、方法重写的注意事项

  • 父类中私有方法不能被重写
    • 因为父类私有方法子类根本就无法继承
  • 子类重写父类方法时,访问权限不能更低
    • 最好就一致
  • 父类静态方法,子类也必须通过静态方法进行重写
    • 静态与类相关,其实算不上重写。

23、final关键字

  • final修饰特点
    • 修饰类,类不能被继承
    • 修饰变量,变量就变成了常量,只能被赋值一次
    • 修饰方法,方法不能被重写
  • final关键字修饰局部变量
    • 基本类型,是值不能被改变
    • 引用类型,是地址值不能被改变,对象中的属性可以改变
  • final修饰变量的初始化时机
    • 类成员变量没有显示初始化时,JVM会默认初始化
    • 加了final修饰后JVM不再默认初始化

24、抽象类

  • 概述
    • 抽象就是看不懂的
  • 抽象类的特点
    • 抽象类和抽象方法必须用abstract关键字修饰
      • abstract class 类名{}
      • public abstract void eat();
    • 抽象类不一定有抽象方法,有抽象方法的类一定是抽象类或接口
    • 抽象类不能实例化,那么抽象类如何实例化呢?
      • 按照多态的方式,由具体的子类实例化。其实这也是多态的一种,抽象类多态。
    • 抽象类的子类
      • 要么是抽象类
      • 要么重写抽象类中所有抽象方法
  • 抽象类成员特点
    • 成员变量:既可以是变量,也可以是常量。abstract不能修饰成员变量
    • 构造方法:有。用于子类访问父类数据的初始化。
    • 成员方法:既可以是抽象的,也可以是非抽象的。
  • 抽象类的成员方法特性:
    • 抽象方法:强制要求子类做的事情
    • 非抽象方法:子类继承的事情,提高代码复用性
  • 面试题
    • 面试题1:一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义?
      • 可以。这么做目的是不让其他类创建本类对象,交给子类完成
    • 面试题2:abstract不能和哪些关键字共存
      • static、final、private
      • static和abstract,被abstract修饰的方法没有方法体,static修饰的方法可以用类名.调用,但是类名.调用抽象方法是没有意义的。
      • final和abstract,被abstract修饰的方法强制子类重写,被final修饰的方法不让子类重写,矛盾。
      • private和abstract,abstract修饰方法目的是让子类强制重写,private修饰方法不让子类继承,矛盾。

25、接口

  • 概述
    • 从狭义的角度讲就是指Java中的interface
    • 从广义的角度讲对外提供规则的都是接口
  • 特点
    • 接口用关键字interface表示
      • interface 接口名 {}
    • 类实现接口用implements表示
      • class 类名 implements 接口名 {}
    • 接口不能实例化,那么接口如何实例化呢?
      • 按照多态的方式来实例化
    • 接口的子类
      • 可以是抽象类。但意义不大
      • 可以是具体类。要重写接口中所有抽象方法(推荐)
  • 接口成员特点
    • 成员变量:只能是常亮,并且是静态公共的。
      • 默认修饰符:public static final
    • 构造方法:无
    • 成员方法:只能是抽象方法
      • 默认修饰符:public abstract

26、抽象类和接口的区别

  • 成员区别
    • 抽象类
      • 成员变量:可以变量,也可以常量
      • 构造方法:有。
      • 成员方法:可以抽象,也可以非抽象
    • 接口
      • 成员变量:只能是常量
      • 成员方法:只能是抽象
  • 关系区别
    • 类与类:继承,单继承
    • 类与接口:实现,单实现,多实现
    • 接口与接口:继承,单继承,多继承
  • 设计理念区别
    • 抽象类:被继承体现的是“is a”关系。抽象类中定义的是该继承体系的共性功能。
    • 接口:被实现体现的是“like a”关系。接口中定义的是该继承体系的扩展功能。

27、如何编译运行带包的类

  • javac编译的时候带上-d即可
    • javac -d . HelloWorld.java
  • 通过java命令执行。
    • java 包名.HellWord

28、四种权限修饰符

这里写图片描述

29、类及其组成所使用的常见修饰符

  • 修饰符:
    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,final
    • 抽象修饰符:abstract
  • 类:

    • 权限修饰符:默认修饰符,public
    • 状态修饰符:final
    • 抽象修饰符:abstract

    • 用的最多的就是:public

  • 成员变量:

    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,final

    • 用的最多的就是:private

  • 构造方法:

    • 权限修饰符:private,默认的,protected,public

    • 用的最多的就是:public

  • 成员方法:

    • 权限修饰符:private,默认的,protected,public
    • 状态修饰符:static,final
    • 抽象修饰符:abstract

    • 用的最多的就是:public

  • 除此以外的组合规则:

    • 成员变量:public static final
    • 成员方法:
      • public static
      • public abstract
      • public final

30、内部类访问特点

  • 内部类可以直接访问外部类的成员,包括私有。
  • 外部类要访问内部类的成员,必须创建对象。
  • 创建内部类对象格式:
    • 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
  • 成员内部类被静态修饰后的访问方式:
    • 外部类名.内部类名 对象名 = 外部类名.内部类对象;
  • 实例

    public class Test {
        public static void main(String[] args) {
            Outer.Inner oi = new Outer.Inner();
            oi.method();
    
            Outer.Inner2.print();
        }
    }
    
    class Outer {
        static class Inner {
            public void method() {
                System.out.println("method");
            }
        }
    
        static class Inner2 {
            public static void print() {
                System.out.println("print");
            }
        }
    }
    
  • 面试题

  • 要求:使用已知的变量,在控制台输出30,20,10。
    
    class Outer {
        public int num = 10;
        class Inner {
            public int num = 20;
            public void show() {
                int num = 30;
                System.out.println(?); //num
                System.out.println(??); //this.num
                System.out.println(???); //Outer.this.num
            } 
        }
    }
    class InnerClassTest {
        public static void main(String[] args) {
            Outer.Inner oi = new Outer().new Inner();
            oi.show();
        }   
    }   
    
  • 局部内部类:在方法中定义的内部类

    public class Test {
        public static void main(String[] args) {
            Outer o = new Outer();
            o.method();
        }
    }
    
    class Outer {
        public void method() {
            final int num = 10; //jdk1.8后不用再加final
            class Inner {
                public void print() {
                    System.out.println(num);
                }
            }
    
            Inner i = new Inner();
            i.print();
        }
    }
    
  • 匿名内部类:内部类的简化写法

    • 前提:存在一个类或者接口
      • 这里的类可以是具体类也可以是抽象类。
    • 格式:

    • new 类名或者接口名(){
      重写方法;
      }
    • 本质:是一个继承了该类或者实现了该接口的子类匿名对象。
    • 实例

      public class Test {
          public static void main(String[] args) {
              PersonDemo pd = new PersonDemo ();
      
              //如何调用PersonDemo中的method方法呢?
              pd.method(new Person() {
                  public void show() {
                      System.out.println("Hello World");
                  }
              });
          }
      }
      
      //这里写抽象类,接口都行
      abstract class Person {
          public abstract void show();
      }
      
      class PersonDemo {
          public void method(Person p) {
              p.show();
          }
      }
      
    • 面试题
    • 按照要求,补齐代码
      interface Inter { void show(); }
      class Outer { //补齐代码 }
      class OuterDemo {
      public static void main(String[] args) {
      Outer.method().show();
      }
      }
      要求在控制台输出”HelloWorld”

      public class Test {
          public static void main(String[] args) {
              Outer.method().show(); //连续两次调用方法,说明返回的是个对象
          }
      }
      
      //按照要求,补齐代码
      interface Inter { 
          void show(); 
      }
      
      class Outer { 
          //补齐代码 
          public static Inter method() {
              return new Inter() {
                  public void show() {
                      System.out.println("Hello World");
                  }
              };
          }
      }
      //要求在控制台输出”Hello World”
      
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值