JavaSE-面向对象总结

1. 封装

封装的最基本单位是对象,封装的最基本目标是“高内聚、低耦合”。通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象,我们在类中编写的方法就是对实现细节的一种封装,我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口。

2. 继承

  1. Java是单继承
  2. 继承好处:提高了代码的复用性、维护性
  3. 继承弊端:类的耦合性增强了
  4. 继承体现的关系:is a
  5. 设计时可以抽象子类的共有特征来构成父类
  6. this:代表本类当前对象的引用
  7. super:代表父类对象的引用,super会先去父类找,父类没有就去爷爷类找,Object类也没有就编译报错
  8. 对构造的调用:只能出现在其他构造的第一句;因此this()和super()不能同时出现在同一个构造中;在成员方法中不能用this()或super()调用构造
  9. 继承中变量的访问顺序:
    1. 子类局部范围找
    2. 子类成员范围找
    3. 父类成员范围找
    4. 如果都没有就报错(不考虑父类的父类)
  10. 继承中成员方法的访问顺序:
    1. 子类成员范围找
    2. 父类成员范围找
    3. 如果都没有就报错(不考虑父类的父类)
  11. 继承中构造方法的访问特点:
    1. 子类中所有构造方法第一条语句默认都是:super(),因为子类会继承父类中的数据,可能还会使用父类中的数据,因此子类初始化之前,一定要先完成父类数据的初始化。
    2. 若父类中没有无参构造,只有带参构造,需要显示使用super去调用父类带参构造方法,因此创建类时最好都写上无参构造。
  12. 构造代码块:直接在类中定义且没有加static关键字的代码块;构造代码块在每次创建对象时被调用,且优先于构造方法执行
    1. 可以统计创建了多少对象
    2. 可以放创建对象之前需要执行的代码
  13. 方法重写时子类方法访问权限不能比父类的低
  14. 一个类如果没有父类,默认继承自Object类
  15. 运行时,父类先进方法区;父类中的属性,会跟随子类对象进入到堆内存

3. 多态

  1. 多态简单理解:同一个对象在不同时刻表现出不同形态
  2. 多态的前提和体现:
    1. 有继承/实现关系
    2. 有方法重写
    3. 有父(类/接口)引用指向(子/实现)类对象
  3. 多态好处:提高了程序的扩展性;如在定义方法时,使用父类作为参数,将来使用时用具体子类参与操作
  4. 多态弊端:不能使用子类特有功能
  5. 多态中成员的访问特点:只有运行时的非静态方法看右边
    1. 编译时:变量和方法都看左边。因为编译时右边new的对象还没有被调入到堆内存。
    2. 运行时:变量看左边,静态方法看左边,非静态方法看右边。因为左边的声明类型可能是接口,方法是抽象的,所以运行时方法要看右边的。
  6. 向上转型:子类转换为父类,父类引用指向子类对象,安全
  7. 向下转型:父类转换为子类,父类引用转为子类引用,不安全
  8. instanceof运算符:判断一个对象是否为一个类的实例

4. 抽象类

  1. 抽象类主要对进行抽象
  2. 抽象类体现了模板方法模式
  3. 使用abstract修饰抽象类和抽象方法
  4. 一个没有方法体的方法应该定义为抽象方法
  5. 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
  6. 抽象类的子类要么重写抽象类中的所有抽象方法,要么是抽象类
  7. 抽象类不能实例化,但有构造方法,用于子类访问父类数据的初始化
  8. abstract和final不能同时使用,因为abstract是让子类重写,而final是不可重写
  9. abstract和private不能同时使用,因为abstract是让子类重写,private要求只能本类使用,子类根本继承不了
  10. abstract和static不能同时使用,因为abstract是让子类重写,static修饰的方法不能被重写

5. 接口

  1. 接口主要对行为进行抽象

  2. 一个类/接口可以同时实现/继承多个接口

  3. 接口不能直接实例化,可以通过实现类对象实例化

  4. 接口的实现类要么重写接口中的所有抽象方法,要么是抽象类

  5. 接口没有构造方法

  6. 接口中的成员变量只能是常量,默认修饰符为public static final

  7. 接口中的方法只能是抽象方法,默认修饰符为public abstract

  8. 接口多实现冲突(冲突即重名):

    1. 接口常量冲突:该常量不会被继承,只能通过原接口访问
    2. 接口抽象方法冲突:只需重写一个
    3. 接口默认方法冲突:实现类必须重写这个默认方法;因为是类,所以不需要加default
    4. 接口静态方法冲突:静态只供接口调用,对实现类无影响
  9. 接口多继承冲突:

    1. 接口常量冲突:该常量不会被继承,只能通过原接口访问
    2. 接口抽象方法冲突:只会继承一个
    3. 接口默认方法冲突:子接口必须重写这个默认方法;因为是接口,所以需要加default
    4. 接口静态方法冲突:静态只供接口调用,对子接口无影响
  10. 实现类继承父类又实现接口冲突:

    1. 类和接口常量冲突:该常量不会被继承,只能通过原接口或父类名访问
    2. 类和接口抽象方法冲突:只会继承一个
    3. 类和接口默认方法冲突:实现类优先使用父类的
    4. 类和接口静态方法冲突:实现类只能访问父类的静态方法
  11. 接口的组成:

    1. 常量
    2. 抽象方法
    3. 默认方法(Java 8)
    4. 静态方法(Java 8)
    5. 私有方法(Java 9)
  12. 接口中默认方法不是抽象方法,所以不强制被重写,但可以被重写,重写的时候去掉default关键字

    接口中默认方法的定义格式:
    public default 返回值类型 方法名(参数列表) {}
    
    定义时public可以省略,default不能省略
    
  13. 接口中静态方法只能通过接口名调用,不能通过实现类名或者对象名调用,因为接口的静态方法不能被继承

    接口中静态方法的定义格式:
    public static 返回值类型 方法名(参数列表) {}
    
    定义时public可以省略,static不能省略
    
  14. 接口中私有方法:当两个默认方法或者静态方法中包含一段相同的代码实现时,程序必然考虑将这段实现代码抽取成一个共性方法,而这个共性方法是不需要让别人使用的,因此用私有给隐藏起来,这就是Java 9增加私有方法的必然性

    接口中私有方法的定义格式:
    格式1private 返回值类型 方法名(参数列表) {}
    格式2private static 返回值类型 方法名(参数列表) {}
    
    默认方法可以调用私有的静态方法和非静态方法
    静态方法只能调用私有的静态方法
    

6. 内部类

  1. 内部类的访问特点:

    1. 内部类可以直接访问外部类的成员,包括私有
    2. 外部类要访问内部类的成员,必须创建对象
  2. 外界创建非私有的成员内部类:

    外部类名.内部类名 对象名 = 外部类对象.内部类对象;
    如:Outer.Inner oi = new Outer().new Inner();
    
  3. 局部内部类是在方法中定义的类,外界无法直接使用,需要在方法内部创建对象并使用。

  4. 局部内部类只能访问final的局部变量,在JDK1.8之后,若没有加final则会默认加上。因为局部变量随方法结束而销毁时,局部内部类对象可能还没有被回收,因此被内部类访问的局部变量会被拷贝一份到内部类中,若局部变量不是final的,其值就可能被修改,而内部类对象中保存的是其原来的值,这就会出现数据不同步的问题。

  5. 匿名内部类:本质是一个继承了该类或者实现了该接口的子类匿名对象

    格式:
    new 类名或接口名() {
    	重写方法;
    }
    

7. 成员变量和局部变量的区别

成员变量局部变量
在类中,方法外在方法内或方法声明上
堆内存栈内存
随对象的存在而存在随方法的调用而存在
有默认值无默认值

8. 访问权限

权限同类同包不同包子类不同包非子类
public
protected
default(不写)
private

外部类只能用public或default(不写)这两种修饰符;内部类四种都可以用

protected权限用法:只能在子类中使用super才能访问父类

private修饰的方法不能被重写,因为private修饰的成员只能在本类中访问

9. static

  1. 被static修饰的内容在静态区中,随着类的加载而加载;不属于对象,而是属于类的;凡是本类的对象,都共享同一份。

    class Student {
        private int id;
        private static int idCounter = 0; // idCounter:学号计数器
    
        public Student() {
            // 每当new一个新对象时,自动给id赋值
            id = ++idCounter;
        }
    }
    
  2. 静态代码块:

    1. 特点:当第一次用到本类时,静态代码块执行唯一的一次**(无论创建多少对象,只在第一次的时候执行)**

    2. 典型用途:用来一次性地对静态成员变量进行赋值

    3. 静态代码块优先于构造代码块;构造代码块优先于构造方法

      static {
          // 静态代码块的内容
      }
      
  3. 通过类名访问静态成员变量时,全程和对象就没关系,只和类有关系

  4. 无论成员变量还是成员方法,如果被static修饰了,都推荐使用类名进行调用

  5. 静态不能直接访问非静态,因为在内存中先有静态,后有非静态。–>前人不知道后人,但后人知道前人

  6. static不可以修饰局部变量,因为静态成员属于类,不属于方法

  7. 静态方法不能使用this,因为this代表当前对象,通过谁调用的方法,谁就是对象,但是静态却与对象没关系

  8. 静态方法可以被继承,但是不能重写。如果父类中有一个静态的方法,子类也有一个与其方法名参数列表相同静态方法,那么该子类的方法会把原来继承过来的父类的方法隐藏,而不是重写。

  9. 静态内部类可以定义静态和非静态的方法和属性,而非静态内部类只能定义非静态方法和属性。因为非静态内部类在创建对象时才出现,若内部有静态成员,则该静态成员需在创建对象前就出现,相互矛盾。

  10. 静态属于类,不属于对象,因此静态不能对象序列化

10. final

  1. 被final修饰的类不能被继承;一个类如果是final的,那么其中所有成员方法都无法被覆盖重写(因为没儿子)

    // 格式
    权限修饰符 final class 类名称 {
    }
    
  2. 被final修饰的方法不能被覆盖重写

    // 格式
    权限修饰符 final 返回值类型 方法名(参数列表) {
    }
    
  3. 被final修饰的局部变量不可改变,一次赋值,终生不变。对于基本类型来说,不可变指变量中的数据不可改变;对于引用类型来说,不可变指变量的地址不可改变

    // 格式 只保证有唯一一次赋值即可
    final 数据类型 变量名;
    
  4. 被final修饰的成员变量同样不可变且没有默认值

    1. 被final修饰的成员变量,要么直接赋值,要么通过构造方法赋值,二者选其一。
    2. 如果选择使用构造方法赋值,那么必须保证类中所有重载的构造方法,都对被final修饰的成员变量赋值。
    3. 被final修饰的成员变量,不能有set方法。

11. 枚举

  1. 枚举是JDK1.5新增的引用数据类型,枚举和类、接口、注解是一个级别,定义枚举的关键字为enum

  2. 所有枚举默认继承了java.lang.Enum,因此枚举不能继承其他类,但枚举可以实现接口

  3. 每一个枚举及其定义的常量在JVM中都是唯一的,为了达到这个效果,它通过以下方法来确保:

    1. 私有构造,无法正常的new对象
    2. 无法通过反射的方式创建枚举对象
    3. 无法通过clone()方法克隆枚举对象
    4. 类加载时创建,保证线程安全
    5. 对序列化进行特殊处理,防止反序列化时创建新的对象
  4. 枚举中每一个常量都可以看作是该枚举的实例,默认被public static final修饰

  5. 枚举中的常量一般大写,多个常量之间用逗号分开,最后一个常量后可以写分号也可以不写

  6. 枚举构造默认是private且只能是private;而且构造方法必须写在常量后面,这时最后一个常量后必须写分号

    /**
     * 枚举定义和使用示例
     */
    enum Color {
        // 枚举静态常量
        RED, GREEN, BLUE
    }
    
    enum WebPage {
        /**
         * 自己写了有参构造,因此不会再提供无参构造
         * 而枚举中每一个常量都可以看作是该枚举的实例,因此定义时需要传递参数
         */
        HTML("HTML语言"), CSS("CSS语言"), JAVASCRIPT("JavaScript语言");
        private String describe;
    
        // 枚举构造默认是private且只能是private
        WebPage(String describe) {
            this.describe = describe;
        }
    
        public String getDescribe() {
            return describe;
        }
    }
    
    public class EnumTest {
        public static void main(String[] args) {
            Color red = Color.RED;
            System.out.println(red);
            System.out.println(WebPage.JAVASCRIPT.getDescribe());
            /**
             * 结果:
             * RED
             * JavaScript语言
             */
        }
    }
    

若有错误或补充,欢迎私信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值