== 和 equals 方法

== 代表比较双方是否相同。

  • 比较基本类型,表示值相同
  • 比较引用类型,表示地址相等即为同一对象

Object类中定义有:public boolean equals(Object obj)方法,提供定义“对象内容相等”的逻辑

Object 的 equals 方法默认就是比较两个对象的 hashcode,是同一个对象的引用时返回 true 否则返回 false。可以根据自己的要求重写equals方法。

封装

需要让用户知道的才暴露出来,不需要让用户知道的全部隐藏起来,这就是封装。即封装就是把对象的属性和操作结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。

编程中封装的具体优点:

  • 提高代码的安全性。
  • 提高代码的复用性。
  • “高内聚”:封装细节,便于修改内部代码,提高可维护性
  • “低耦合”:简化外部调用,便于调用者使用,便于扩展和协作。

多态

多态指的是同一个方法调用,由于对象不同可能会有不同的行为。现实生活中,同一个方法,具体实现会完全不同。 比如:同样是调用人“吃饭”的方法,中国人用筷子吃饭,英国人用刀叉吃饭,印度人用手吃饭。

多态的要点:

  • 多态是方法的多态,不是属性的多态(多态与属性无关)。
  • 多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象。
  • 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。

抽象类和抽象方法

抽象方法

使用abstract修饰的方法,没有方法体,只有声明。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。

抽象类

包含抽象方法的类就是抽象类。通过abstract方法定义规范,然后要求子类必须定义具体实现。通过抽象类,我们就可以做到严格限制子类的设计,使子类之间更加通用。

抽象类的使用要点

  1. 有抽象方法的类只能定义成抽象类

  2. 抽象类不能实例化,即不能用new来实例化抽象类。

  3. 抽象类可以包含属性、方法、构造方法。但是构造方法不能用来new实例,只能用来被子类调用。

  4. 抽象类只能用来被继承。

  5. 抽象方法必须被子类实现

接口

为什么需要接口? 接口和抽象类的区别?

  • 接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面地专业地实现了:规范和具体实现的分离。

  • 抽象类还提供某些具体实现,接口不提供任何实现,接口中所有方法都是抽象方法。接口是完全面向规范的,规定了一批类具有的公共方法规范。

  • 接口和实现类不是父子关系,是实现规则的关系。比如:定义一个接口Runnable,Car实现它就能在地上跑,Train实现它也能在地上跑,飞机实现它也能在地上跑。就是说,如果它是交通工具,就一定能跑,但是一定要实现Runnable接口。

接口使用

[访问修饰符]  interface 接口名   [extends  父接口1,父接口2…]  {
常量定义;
方法定义;
}
  • 访问修饰符:public 或默认
  • extends:可多继承
  • 常量:接口中的属性只能是常量,总是:public static final 修饰 or 省略
  • 方法:接口中的方法只能是:public abstract or 省略
  • JDK1.7之前,接口中只能包含静态常量、抽象方法,不能有普通属性、构造方法、普通方法。
  • JDK1.8后,接口中包含普通的静态方法

内部类

内部类的作用:

  1. 内部类提供了更好的封装。只能让外部类直接访问,不允许同一个包中的其他类直接访问。

  2. 内部类可以直接访问外部类的私有属性,内部类被当成其外部类的成员。 但外部类不能访问内部类的内部属性。

  3. 接口只是解决了多重继承的部分问题,而内部类使得多重继承的解决方案变得更加完整。

内部类的使用场合:

  1. 由于内部类提供了更好的封装特性,并且可以很方便的访问外部类的属性。所以,在只为外部类提供服务的情况下可以优先考虑使用内部类。

  2. 使用内部类间接实现多继承:每个内部类都能独立地继承一个类或者实现某些接口,所以无论外部类是否已经继承了某个类或者实现了某些接口,对于内部类没有任何影响。

String

String 类对象代表不可变的Unicode字符序列,因此我们可以将String对象称为“不可变对象”。 那什么叫做“不可变对象”呢? 指的是对象内部的成员变量的值无法再改变。

字符串常量拼接时的优化

在遇到字符串常量之间的拼接时,编译器会做出优化,即在编译期间就会完成字符串的拼接。

String s1 = "hello" + " world";
String s2 = "hello world";
System.out.println(s1 == s2); // true String s3 = "hello";
String s4 = " world";
//编译的时候不知道变量中存储的是什么,所以没办法在编译的时候优化
String s5 = s3 + s4;
System.out.println(s2 == s5); //false

String Pool

字符串常量池(String Pool)保存着所有字符串字面量,这些字面量在编译时期就确定。使用String的 intern() 方法在运行过程中将字符串添加到常量池中。

当一个字符串调用 intern() 方法时,若 String Pool 中已存在字符串和该字符串值相等(通过equals()方法判断),则返回String Pool 中字符串的引用;否则,就在S P 中添加一个新字符串并返回其引用。

String s1 = new String("aaa");
String s2 = new String("aaa");
sout(s1 == s2); // false String s3 = s1.intern();
String s4 = s2.intern();
sout(s3 == s4); // true

若以字面量形式创建字符串,会自动将字符串放入String Pool。

String s5 = "bbb";
String s6 = "bbb";
sout(s5 == s6); // true
  • Java 7 之前,String Pool 被放在运行时常量池中,属于永久代
  • 在Java 7, String Pool 被移到堆中(因为永久代空间有限,在大量使用字符串的场景会导致 OutOfMemoryError 错误)

StringBuffer、StringBuilder

StringBuffer和StringBuilder非常类似,均代表可变的字符序列(无final修饰的char value[])。 这两个类都是抽象类AbstractStringBuilder的子类,方法几乎一模一样。

区别:

  1. StringBuffer JDK1.0版本提供的类,线程安全,做线程同步检查(synchronized), 效率较低。

  2. StringBuilder JDK1.5版本提供的类,线程不安全,不做线程同步检查,因此效率较高。 建议采用该类。

自动装箱/拆箱

自动装箱和拆箱就是将基本数据类型包装类之间进行自动的互相转换。

  • 自动装箱:基本类型的数据处于需要对象的环境中时,会自动转为“对象”。

    Integer i = 100;
    // 相当于
    Integer i = Integer.valueOf(100);
  • 自动拆箱:每当需要一个值时,对象会自动转成基本数据类型,没必要再去显式调用intValue()、doubleValue()等转型方法

    Integer i = 100;
    int j = i; // 自动拆箱
    // 相当于
    int j = i.intValue();

包装类的缓存

整型、char类型所对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存处理,其目的是提高效率。

缓存原理:

  • 若数据在 -128~127 区间,则在类加载时就已经为该区间的每个数值创建了对象,并将这256个对象放在cache数组中
  • 每当自动装箱过程发生时 (或者手动调用valueOf()时),就会先判断数据是否在该区间,如果在则直接获取数组中对应的包装类对象的引用,如果不在该区间,则会通过new调用包装类的构造方法来创建对象。

异常机制

Java是采用面向对象的方式来处理异常的。处理过程:

  1. 抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象,停止当前执行路径,并把异常对象提交给JRE。

  2. 捕获异常:JRE得到该异常后,寻找相应的代码来处理该异常。JRE在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止。

Java 异常类层次结构:

  • Error 是程序无法处理的错误,表示运行应用程序中较严重问题。

  • Exception 是程序本身能够处理的异常。Exception类是所有异常类的父类,分为:

    • RuntimeException 运行时异常

      如被 0 除、数组下标越界、空指针(访问空对象成员)等

    • CheckedException 已检查异常

      所有不是RuntimeException的异常,统称为Checked Exception.

捕获异常

  • try-catch-finally

    • 如果异常类之间有继承关系,越是顶层的类,越放在下面;或者直接把多余的catch省略掉,即先捕获子类异常再捕获父类异常
    • 即使try和catch块中存在return语句,finally语句也会执行。是在执行完finally语句后再通过return退出。
    • finally语句块只有一种情况是不会执行的,那就是在执行finally之前遇到了 System.exit(0) 结束程序运行。
  • throws

    如果一个方法中可能产生某种异常,但是并不能确定如何处理这种异常,则应根据异常规范在方法的首部声明该方法可能抛出的异常。

    public static void readFile(String fileName) throws FileNotFoundException,IOException {...}

    方法重写中声明异常原则:子类重写父类方法时,如果父类方法有声明异常,那么子类声明的异常范围不能超过父类声明的范围

☕Java 面向对象进阶内容的更多相关文章

  1. Java面向对象进阶篇(包装类,不可变类)

    一. Java 8的包装类 Java中的8种基本数据类型不支持面向对象的变成机制,也不具备对象的特性:没有成员变量,方法可以调用.为此,Java为这8 种基本数据类型分别提供了对应的 包装类(Byte ...

  2. Java面向对象进阶篇(抽象类和接口)

    一.抽象类 在某些情况下,父类知道其子类应该包含哪些方法,但是无法确定这些子类如何实现这些方法.这种有方法签名但是没有具体实现细节的方法就是抽象方法.有抽象方法的类只能被定义成抽象类,抽象方法和抽象类 ...

  3. Java面向对象进阶篇(内部类)

    一. 概念 大部分时候,类被定义成一个独立的程序单元.有时候把一个类放在另一个类内部定义,这个类被称为内部类,包含内部类的类也被称为外部类. 内部类的主要作用: 内部类提供良好的封装,可以把内部类隐藏 ...

  4. python_面向对象进阶(7)

    第1章 面向对象特性—继承(补充) 1.1 接口类.抽象类介绍 1.2 接口类 1.3 接口类应用过程 1.3.1 第一版:完成多种支付方式接口 1.3.2 第二版: 归一化设计,统一支付方式 1.3 ...

  5. 夯实Java基础系列1:Java面向对象三大特性(基础篇)

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...

  6. Java面向对象程序设计笔记 • 【目录】

    持续更新中- 我的大学笔记>>> 章节 内容 实践练习 Java面向对象作业目录(作业笔记) 第1章 Java面向对象笔记 • [第1章 面向对象] 第2章 Java面向对象笔记 • ...

  7. Python全栈开发【面向对象进阶】

    Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...

  8. 谈谈Java面向对象的三大特性

    Java面向对象的三大特性就是指封装.继承.多态了. 一.封装: 概念:封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. (举例:笔记本电脑就是一个封装体,Java语言中最小的封装体就是函数 ...

  9. 实验二 Java面向对象程序设计

    实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计 ...

随机推荐

  1. Cplex用法

    Cplex用法 1.将问题转化为LP问题: cplex -c read mps/nw460.mps change problem type lp opt 2.将问题转化为LP问题并输出问题: cple ...

  2. 【Android】安卓四大组件之Activity(一)

    [Android]安卓四大组件之Activity(一) 前言 Activity是Android学习中的一个重要组件,想要对其进行系统的了解可以分为几块内容,这一大章节的内容是有关于activity之间 ...

  3. IoC容器-Bean管理XML方式(注入内部bean和级联赋值)

    注入属性-内部bean和级联赋值 (1)一对多关系:部分和员工 一个部门有多个员工,一个员工属于一个部门 部门是一,员工是多 (2)在实体类之间表示一对多关系 (3)在spring配置文件中进行配置 ...

  4. django之djangorestframework序列化操作

    只介绍序列化操作:serializers.ModelSerializer 与 serializers.Serializer 使用序列化的目的:将数据序列化成  JSON 对象 当页面上需要动态加载内容 ...

  5. Java安全之BCEL ClassLoader

    目录 Java安全之BCEL ClassLoader 写在前面 About BCEL 调试分析 食用姿势 Fuzz反序列化Gadget Fastjson BCEL Payload Thymeleaf ...

  6. 使用Hot Chocolate和.NET 6构建GraphQL应用(7) —— 实现Query分页功能

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 GraphQL中的查询分页相对来说是查询中比较难理解的,接口的Schema也和其他不一样.在这篇文章中,我们 ...

  7. JSP页面重定向与页面内容转发

    重定向:属于两次请求+响应,客户端浏览器地址栏会改变. 转发:属于一次请求+一次响应,客户端浏览器地址栏不会改变. 重定向: response.setHeader("action" ...

  8. listview界面显示

    1.布局写listview      2.找到listview           3.封装新闻数据到list集合中 ,目的是为adapter提供数据展示.     4.封装一个Adapter类继承B ...

  9. PHP中常见的数字掐头去尾操作方法

    四舍五入round round( float $val[, int $precision = 0[, int $mode = PHP_ROUND_HALF_UP]] ) : float 对浮点数进行四 ...

  10. 网络层主要协议与arp欺骗

    网络层主要协议与arp欺骗 目录 网络层主要协议与arp欺骗 一.网络层(Network Layer) 1.网络层的功能 2.IP数据报(IP Datagram) 二.网络层的主要协议 1.ICMP协 ...