指将数据及相关操作绑定在一起的一种编程机制,使其构成一个不可分割的独立实体。
在Java中,类就是这样一种结构。
当然,数据被保护在类的内部,是为了尽可能地隐藏内部的细节,只保留一些对外"接口"
使之与外部发生联系。
把抽象出来的数据(属性), 和对数据的操作(方法)封装在一起, 数据被保护在内部, 程序的其他部分只有被授权的操作(方法), 才能对数据进行操作.
public
的get
方法,访问成员变量的值get
方法的命名规则getXxx()
,小驼峰public
的set
方法,修改成员变量的值set
方法的命名规则setXxx(参数)
,小驼峰使用private私有化成员变量,并提供方法给外界访问时,需要注意:
成员变量的访问权限应该尽量收紧,尽量私有化,当然有必要时也可以给外界权限直接访问。
对于boolean类型的成员变量来说,Getter方法的名字比较特殊,采用isXxx(Xxx是变量名)
的形式。
复用代码(复用父类的成员:成员变量、成员方法,不涉及static
)
权限修饰符 class 类名 extends 被继承的类/已有的类 {类体}
extends
(扩展)关键字去继承另一个类,这个类被称为子类(subClass
),被继承的类称为父类(基类baseClass
,超类superClass
)父子类之间的关系:子类is-a父类的关系
子类类型 对象名 = (子类类型) 父类的引用
引用数据类型的转换前提:存在继承关系
强转后的引用类型必须能够真正的指向该对象,即强转后的引用的类型必须是该对象的类型或者其父类型
@Override注解的作用:标记该方法是否是重写(覆盖)父类的方法
父类的修改能够体现到所有的子类中,子类无条件接收父类中的成员
extends
关键字后面只能有一个类extends
关键字,祖先类就是Object
类,Object
类是所有类的祖先类)protected
成员private
成员有没有继承? ---- 继承了,但是没有访问权限先父类的成员进行默认赋值,显示赋值,构造器
再子类的成员赋值,赋值顺序保持一致
为什么父类的赋值先执行?
因为父类的构造器是先执行的,
原因:在子类的构造器中有一个默认隐藏的语句super()
,
此时如果子类的构造器中没有this(实参)
,也没有super()
, ----> 子类对象的隐式初始化
显示初始化就是在子类的构造器中用代码把super
显示的写出来
super
关键字指向, 近似看做super指向当前子类对象的父类对象)this
指向当前子类对象)super
调用父类的构造方法,也没有用this
去调用自己的构造方法。达成上述两个条件,则JVM在初始化子类对象时进行隐式初始化,永远先执行父类的构造方法,顺序为:
(近似)
的引用,指向的是子类对象中父类的成员区域,(近似)
看作是指向父类对象super(实参)
表示调用的是父类某个构造方法super
进行区分(通过super.
去调用父类方法)this
—> 引用,指向的是当前的对象super
—> 近似引用,指向的是子类对象中的父类成员区域,近似看做指向父类的对象this(实参)
—> 调用子类自身的构造super(实参)
—> 调用的是父类的构造器this
—> 区分同名成员变量跟局部变量super
—> 区分同名的父子类中的成员变量this
—> 不受访问权限的控制super
—> 受访问权限的控制this
和super
在构造器的第一行
-------> this
和super
在一个构造方法里面不能同时出现
我们将程序的运行分成两部分:
第一部分:类加载
首先程序要从main
方法启动,这意味着首先要触发,装有main
方法的那个类的类加载。
类加载过程中,一定要考虑连环触发类加载的情况:
类加载这个过程中,静态代码块的代码一定会执行,不要忘记了。
如果有静态成员变量的显式赋值,那么显式赋值和静态代码块,按照代码的书写顺序从上往下执行。
类加载整个程序运行期间只有一次,如有通过继承连环触发类加载,那么顺序是先父后子
,从最顶层父类开始。
第二部分:创建对象
this(参数)
,也可能是super(参数)
)
super()
指向父类的无参构造器。
父类引用指向父类的对象(Father father = new Father()
)
访问的范围:父类
访问的结果:父类
子类引用指向子类的对象(Son son = new Son()
)
访问的范围:父类 + 子类
访问的结果:子类
父类的引用指向子类的对象(Father fs = new Son()
)
访问的范围:父类
访问的结果:父类
结论:
对于访问范围来说 ----> 取决于引用的类型(编译看左边)
对于访问结果来说 ----> 取决于引用的类型(运行也看左边)
对象名.成员方法
调用方法的机制父类引用指向父类的对象(father.
)
访问的范围:父类
访问的结果:父类
子类引用指向子类的对象(son.
)
访问的范围:子类
访问的结果:子类
父类的引用指向子类的对象(fs.
)
访问的范围:父类
访问的结果:子类
结论:
对于访问范围来说 ----> 取决于引用的类型(编译看左边)
对于访问结果来说 ----> 取决于具体的对象的类型(运行看右边)
@override
:用来标记或简称这个方法是不使用重写父类的方法
快捷方式:直接在子类种写跟父类同名的方法名,直接回车
快捷键:alt + enter
-> 选择重写方法
// 成员方法的语句
[ 访问权限修饰符] 返回值类型 方法名( 形参列表){
// 方法体
}
说明:
@Override
注解标记会报错)final
修饰的方法不能被重写权限修饰符 final 方法的返回值类型 方法名(形参列表) { 方法体}
final
修饰的常量数据类型可以是基本数据类型
- final
修饰基本数据类型 —> 变量的值不能改变 final int a = 1;
也可以是引用数据类型
- final
修饰引用数据类型 —> 表示这个引用不能发生变化,指向不能改变,但是对象的状态是可以改变的
final 数据类型 成员变量名
)final 数据类型 静态成员变量名;
字面意思,同一事物在不同情况下所表现出来的不同的状态
说明:
总结:
Java中的多态指的是,同一个父类引用指向不同子类对象时,调用同名成员方法,根据指向实际对象的不同,得到的行为也会随之不不同。
final
修饰的类不能继承final
修饰的方法static
方法private
方法父子类种同名的成员(成员变量、成员方法)
.
出来的范围,编译的角度)结论:
animal.work();
强转后的引用类型必须能够真正的指向该对象,即强转后的引用的类型必须是该对象的类型或者其父类型。
强转失败会导致程序抛出异常:ClassCastException
,导致程序终止执行。正是由于强转的条件苛刻,而且失败后果很严重,所以Java当中提供了检测手段,来保障强转的安全性。需要使用关键字:instanceof
引用 instanceof 类名
结果:
eg:
GrandFather gf = new Son();
System.out.println(gf instanceof GrandFather); // true
System.out.println(gf instanceof Father); // true
System.out.println(gf instanceof Son); // true
System.out.println(gf instanceof Grandson); // false
方法的实参数据类型,需要和方法的形参数据类型保持一致?
方法名(实参)