Java学习笔记-全栈-Java基础-06-面向对象中的重点

1. 静态初始化块

在类中使用static修饰一个代码块,会在创建类的时候执行。(相当于python对象中的init魔法方法)

static{
	初始化代码
}

静态初始化块遵循继承树回溯,会从父类静态初始化块开始直到调用本类静态初始化块。

this和super都是指向对象而非类,而静态xx先于对象产生,因此this与super都是非静态用法。

2. 传值机制

对于任意数据类型,传递的都是copy,但是:

  • 基本数据类型:copy不改变原参数
  • 引用数据类型:引用类型指的是对象的地址,因此改变copy指向对象的指,原参数指向对象的值也会发生改变

3. 静态导入

用于导入指定类的静态属性

  • Import static java.lang.Math.*; //导入Math中所有静态属性
  • Import static java.lang.Math.PI; //导入静态属性PI

4.重写与重载方法的三个要求

重写:子类中方法与父类中方法同名;
重载:当前类中方法同名

4.1 重写的三个要求

  1.“==”: 方法名、形参列表相同。
  2.“≤”:返回值类型和声明异常类型,子类小于等于父类。
  3.“≥”: 访问权限,子类大于等于父类。

4.2 重载

构成方法重载的条件:形参类型、形参个数、形参顺序不同

5. 最常见被重写的Object

5.1 重写toString

经常需要打印对象,重写它的toString即可。

5.2 重写equals

5.2.1 ==与equals

==比较的是两个对象的地址是否相同,即是否是同一个对象。若为数字则比较值

Equals比较的是两个对象的内容是否相同。

String s1 = new String(“test”);
String s2 = new String(“test”);
s1==s2 
//-->false,显然这是两个不同的对象
s1.equals(s2) 
//-->true,显然对象的内容相同

String s1 = “test”;
String s2 = “test”;
s1==s2, 
//-->true. 直接使用双引号引起来的为字符串常量,被保存在常量池中。
//只要值相同,任意多个引用都指向该常量。

字符串拼接在编译的时候已完成(置于静态区),因此对象“a”+“b”和对象“ab” 相等。

  • equals用于比较“两个对象的内容是否相同”。但实际上两个对象“相同”并不需要完全一致,可能只需要某个属性相同即可,比如id,因此需要重写equals

6. 继承树追溯

静态代码块和构造方法都是由父类到子类,属性和方法是由子类到父类

7. 通过访问控制符实现封装

修饰符 同一个类 同一个包 子类 所有类 别名
private * 私有
default * * 包内传递
protected * * * 子类传递
public * * * * 公共

封装办法:

  • 对于属性,一般私有化,方便在类中实现对属性的对外控制(如判断合法化),避免多个用户对其不合法操作或更改代码时导致混乱。一般的编辑器都有自动生成快捷键。
  • 对于方法,一般公有化。

8. 多态

Java的引用类型分为“编译时类型”,“运行时类型”。当编译类型和运行类型不一致时,就发生了多态。

  • 1.多态是非静态方法的多态,不是属性和的多态(与属性或静态方法无关)
  • 2.三个必要条件:继承、方法重写、父类引用指向子类对象
  • 3.该父类引用调用子类重写的方法,此时形成多态。
  • 4.多态弊端:无法直接调用子类特有方法,需要创建一个新的子类并将该父类引用向下转型。
  • 5.通过父类引用调用的方法若子类有,则调用子类,若没有,则调用父类。(继承树原则)
  • 6.通过父类引用调用的变量一定是父类变量,即便子类重写了该变量,调用的依旧为父类变量的原有值。(即第一条,多态只跟非静态方法有关

8.1 隐藏

隐藏是相对于静态方法和属性而言的。

发生多态时,父类和子类拥有同名的静态方法和成员变量,则不发生动态绑定,实际调用的还是父类的静态方法和成员变量。

10. 抽象类与接口

抽象:定义规范,严格限制子类的设计,使子类之间更加通用。
抽象类中的构造方法不需要被实现,只会被自动调用。
抽象类中可以出现方法的实现(如构造方法)。

接口不提供任何方法的实现,完全面向规范。(jdk8提供了default可以改变这个原则,便于接口扩展)
接口中的属性一定是public static final (只能定义常量,用大写)
接口中的方法一定是 public abstract

10.1 接口的用途

  • 接口能将实现与调用完全分离:调用的时候使用接口的实现a,需要更改实现代码的时候,写一个接口的实现b然后将a替换即可。若没有接口,更改实现代码的时候,客户端也得更改调用方式。


java类没有多继承,接口有多继承。

此外,对于初学者来说,一直不懂接口有什么用。事实上,接口是Java十分神奇的部分,当你逐渐接触框架、设计模式之后,便会感受到接口的魅力。

  • 学会面向接口编程。

10.2 有了接口,为什么还要抽象类?

举个最简单的例子(也是最常见的例子)。
假设有个接口A,拥有20个方法。
对于实现他的类B,即便B实际上只需要用到其中的3个方法,那也将不得不实现所有的20个方法(即便只是写一个空方法)。

倘若加上一个中间层,写一个抽象类C来实现接口A,而抽象类继承接口不需要实现全部的方法,可以进行有选择性的实现。此时B通过继承抽象类C,就可以有选择性的实现想要的方法。

而且,抽象类还可以在接口A的基础上,增加额外的方法,实现对接口的拓展

11. 内部类

以下某些内容,有些只是为了方便理解,可能并不完全准确。

  • 1.内部类只是编译概念,编译成功后便会成为两个不同的类,Outer外部类和Inner内部类编译结束后生成Outer.class和Outer$Inner.class
  • 2.兼具成员和类的性质
  • 3.服务于外部类
  • 4.内可调用外(作为成员,显然可以),外不能直接调用内(作为类,对外部类来说内部类没有new出来)
  • 5.静态和非静态在内部类中不能同时出现(作为成员,要么在栈,要么在method area)
  • 6.静态内部类只具有成员的性质(因此创建的时候用成员访问符 . )
  • 7.使用内部类间接实现多继承:每个内部类都可以独立的集成一个类或实现某些接口。
  • 8.匿名内部类只用一次(常见于形参为接口时直接在形参列表new一个匿名内部类实现接口)
  • 9.局部内部类在方法中,方法结束则释放。在1.8以前,局部内部类访问局部变量,需要用final修饰局部变量才能访问。因为局部变量的生命周期跟方法的声明周期一样,当方法弹栈,这个局部变量也消失了。加上final之后,局部变量会存在常量池,就可以随时访问。

final:java中的关键字,修饰符。
A).如果一个类被声明为final,就意味着它不能再派生出新的子类,不能作为父类被继承。因此,一个类不能同时被声明为abstract抽象类的和final的类。
B).如果将变量或者方法声明为final,可以保证它们在使用中不被改变.
  1)被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。
  2)被声明final的方法只能使用,不能重载。
finally:java的一种异常处理机制。
  finally是对Java异常处理模型的最佳补充。finally结构使代码总会执行,而不管无异常发生。使用finally可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。
finalize:Java中的一个方法名。
Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没被引用时对这个对象调用的。它是在Object类中定义的,因此所的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

内部类的好处:外部类使用时他才会被编译,能够提升性能。

全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务