寒假Day41:JAVA-OOP-OOP基础
生日快乐
- 面向对象的基本概念:类、实例、方法
- 面向对象的实现方式:继承、多态
- JAVA语言本身提供的机制:package、classpath、jar
- JAVA标准库提供的核心类:字符串、包装类型、JavaBean、枚举、常用工具类
- 字段:int类型的字段、string... ;field的意思是“字段”,可以理解成变量.
- 直接把
field
用public
暴露给外部可能会破坏封装性 - 使用方法(
method
)来让外部代码可以间接修改field
: 定义
private
方法的理由是内部方法是可以调用private
方法的,外部不可以。但是外部可以调用一个方法(类似C中的函数),该方法可以调用自身有的private方法。 (外部代码可以调用方法来间接修改private
字段)
-
方法可以让外部代码安全地访问实例字段;
-
外部代码通过public方法操作实例,内部代码可以调用private方法。
-
在创建对象实例时就把内部字段全部初始化为合适的值:利用构造方法;
- 创建实例的时候,实际上是通过构造方法来初始化实例的
- 我对于参数绑定的理解:类似月C中的传参操作。
- 构造方法的名称就是类名。构造方法的参数没有限制,在方法内部,也可以编写任意语句。但是,和普通方法相比,构造方法没有返回值(也没有
void
),调用构造方法,必须用new
操作符。 - 我对于构造方法的理解就是:在C里面,类似于调用最直接最根本的函数的时候直接传入参数,而不是通过其他的方法。
- 任何
class
都有构造方法。如果一个类没有定义构造方法,编译器会自动为我们生成一个默认构造方法,它没有参数、没有执行语句。 - 创建对象实例的时候,先初始化字段,再执行构造方法的代码进行初始化。
- 一个构造方法可以调用其他构造方法,这样做的目的是便于代码复用。调用其他构造方法的语法是
this(…)
- 在一个类中,我们可以定义多个方法。如果有一系列方法,它们的功能都是类似的,只有参数有所不同,那么,可以把这一组方法名做成同名方法。
- 这种方法名相同,但各自的参数不同,称为方法重载(
Overload
)。 - 注意:方法重载的返回值类型通常都是相同的。
- 方法重载的目的是,功能类似的方法使用同一名字,更容易记住,因此,调用起来更简单。
- 使用
extends
关键字来实现继承 - 只允许一个class继承自一个类,只有
Object
特殊,它没有父类 - 子类可以访问父类的
protected
字段,protected
关键字可以把字段和方法的访问权限控制在继承树内部,一个protected
字段和方法可以被其子类,以及子类的子类所访问 - 如果父类没有默认的构造方法,子类就必须显式调用
super()
并给出参数以便让编译器定位到父类的一个合适的构造方法。 - 子类不会继承任何父类的构造方法。子类默认的构造方法是编译器自动生成的,不是继承的。
- 向下转型失败的时候,Java虚拟机会报
ClassCastException
- 为了避免向下转型出错,Java提供了
instanceof
操作符,可以先判断一个实例究竟是不是某种类型 - 继承是is关系,has关系使用组合,比如 A has B,即A可以有一个B实例。
- 在继承关系中,子类如果定义了一个与父类方法签名完全相同的方法,被称为覆写(Override)。
- Java的方法签名包括:方法名和参数。不包括方法返回值。
- 如果方法签名如果不同,就是Overload,Overload方法是一个新方法;如果方法签名相同,并且返回值也相同,就是
Override
。 - 加上
@Override
可以让编译器帮助检查是否进行了正确的覆写。希望进行覆写,但是不小心写错了方法签名,编译器会报错
- 多态的特性:运行期才能动态决定调用的子类方法。
- 多态功能:允许添加更多类型的子类实现功能扩展,却不需要修改基于父类的代码。
- 如果一个父类不允许子类对它的某个方法进行覆写,可以把该方法标记为
final
。用final
修饰的方法不能被Override
如果一个类不希望任何其他类继承自它,那么可以把这个类本身标记为
final
。用final
修饰的类不能被继承。- 对于一个类的实例字段,同样可以用
final
修饰。用final
修饰的字段在初始化后不能被修改。
- 由于多态的存在,每个子类都可以覆写父类的方法,
- 可以在构造方法中初始化final字段,
- 这种方法更为常用,因为可以保证实例一旦创建,其
final
字段就不可修改。 final
修饰符:修饰的方法可以阻止被覆写;修饰的class可以阻止被继承;修饰的field必须在创建对象时初始化,随后不可修改。(更常用)
- 如果父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名,目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法。把一个方法声明为
abstract
,表示它是一个抽象方法,本身没有实现任何方法语句。因为这个抽象方法本身是无法执行的,所以,Person
类也无法被实例化。编译器会告诉我们,无法编译Person
类,因为它包含抽象方法。
- 如果父类定义了一个抽象方法(上层代码只定义规范,本质上是定义接口规范)(因为无法执行抽象方法,因此这个类也必须申明为抽象类),那么在实现子类的时候就必须覆写该方法。
-
通过
abstract
定义的方法是抽象方法,它只有定义,没有实现。抽象方法定义了子类必须实现的接口规范。定义了抽象方法的class必须被定义为抽象类,从抽象类继承的子类必须实现抽象方法;如果不实现抽象方法,则该子类仍是一个抽象类。 -
如果一个抽象类没有字段,所有方法全部都是抽象方法,就可以把该抽象类改写为接口(interface)。当一个具体的
class
去实现一个interface
时,需要使用implements
关键字;在接口中,可以定义default
方法(default
方法的目的是:当我们需要给接口新增一个方法时,会涉及到修改全部子类。如果新增的是default
方法,那么子类就不必全部修改,只需要在需要覆写的地方去覆写新增方法) -
一个类可以实现多个接口,接口之间逗号隔开即可。
-
因为静态字段并不属于实例,所以只要修改的是静态字段,不管是哪一个实例,所有实例的静态字段都会被修改成这个。所以,推荐用类名来访问静态字段。
-
调用实例方法必须通过一个实例变量,而调用静态方法则不需要实例变量,通过类名就可以调用。静态方法类似C中的函数。
- 包没有父子关系,故无继承关系。
- 定义在一个
class
内部的class
称为嵌套类,嵌套类拥有访问private
的权限。 - 包作用域是指一个类允许访问同一个
package
的没有public
、private
修饰的class
,以及没有public
、protected
、private
修饰的字段和方法。 - 漏写运行时所需jar包名,在运行期极有可能抛出
ClassNotFoundException
。