概述
Java学习笔记:封装、继承、多态
- 一、访问修饰符
- 二、封装
- 三、继承
- 四、super关键字
- 五、方法重写
- 六、多态
- 七、绑定机制
- 八、Object类
- equals方法
- hashCode方法
- toString方法
- finalize方法
一、访问修饰符
-
public: 在任何类的函数或定义初始值中可以使用,使用指的是调用、访问、或定义变量。
-
protected: 受保护的,对子类和同一个包中的类公开。
-
默认级别: 向同一个包的类公开。
-
private: 只有这个类内部可以访问。类内部指类的成员函数和初始化对象。(这个限制是对类的而不是对对象的)
-
在同一个包下,不能访问private,在不同包下只能访问public
编译单元: 一个.java文件,一个编译单元里可以有很多个类,但是只有一个类可以是public。
修饰符用于修饰类中的属性,成员方法和类,只有默认级别和public才能修饰类。
二、封装
把抽象出来的属性跟方法封装在一起,数据被保存在内部,程序其他部分只有通过被授权的方法才能进行操作。
可以隐藏实现细节,对数据进行验证,保证安全合理。
-
将属性进行私有化private(不能直接修改属性)
-
提供一个公共的set方法,用于对属性判断并赋值。
-
提供一个公共的get方法,用于获取属性的值。
-
可以将构造器和set方法结合,这样就不会通过构造器绕过set方法对属性的限制。
class Encap{
public int 1;
private int j;//私有化
private String name;//私有化
public Encap(int i,int j,String name){
this.i = i;
setJ(j);//在构造器中使用set方法
setName(name);
}
public int getJ() {
return j;
}
public void setJ(int j) {
//可加入判断条件
this.j = j;
}
public String getName() {
//可加入判断条件
return name;
}
public void setName(String name) {
this.name = name;
}
}
三、继承
继承用于解决代码复用,在父类中定义属性和方法所有的子类只需要通过extends来声明继承父类即可。
class 子类 extends 父类{}
-
子类会自动拥有父类定义的属性和方法,父类又叫超类,基类,子类称为派生类。
-
如果子类中有父类中有过的完全相同的名字的,父类的被隐藏。
-
子类定义了子类型,子类的对象可以被当作父类的对象来使用,赋值给父类的变量,传递给需要父类对象的函数,放进存放父类对象的容器。
-
父类中是private的东西只有父类可用,子类虽然继承但是不能直接用,但是可以通过父类的函数去使用。
package Extends;
public class extends01 {
public int n1 = 100;
protected int n2 = 200;
int n3 = 300;
private int n4 = 400;
//父类提供了一个public方法,返回n4
public int getN4(){
return n4;
}
public extends01(){
System.out.println("extends01()");
}
public void test100(){
System.out.println("test100");
}
protected void test200(){
System.out.println("test200");
}
void test300(){
System.out.println();
}
private void test400(){
System.out.println("test400");
}
}
package Extends;
public class extends02 extends extends01{
public extends02(){
System.out.println("extends02()");
}
public void sayOK(){
System.out.println(n1+n2+n3);
System.out.println(getN4());//可以通过父类的方法来调用私有属性
}
}
子类必须调用父类的构造器,完成父类的初始化。如果父类没有提供无参构造器,必须在子类的构造器中使用super去指定使用父类的构造器完成对父类的初始化,否则编译不通过。
package Extends;
public class extends02 extends extends01{
public static void main(String[] args) {
extends02 extends02 = new extends02();
}
public extends02(){
super();//默认调用父类的无参构造器,系统默认加上。
System.out.println("extends02()");
}
}
extends01()
extends02()
-
Java所有类都是Object类的子类,父类构造器的调用不限于直接父类,可一直追溯到Object类(顶级父类)
-
子类最多只能继承一个父类(直接继承),单继承机制。可以让父类继承其他父类从而使子类继承多个类。
-
子类和父类之间必须满足is-a的逻辑关系(包含关系)
-
子类通过查找关系来返回信息,首先看子类是否有该属性,再看父类,再继续找上级父类直到Object类。
四、super关键字
super代表父类的引用,用于访问父类的属性、方法、构造器。
-
super在使用时,需要放在构造器第一行,因此和this()不能共存在一个构造器中。
-
super在访问父类的属性和方法时不可以访问private属性和private方法。
-
super的访问不限于直接父类,上级父类和本类中有同名的成员,也可以使用super去访问成员,多个父类中都有同名的成员,super遵循就近原则。
-
当子类中有和父类的属性和方法重名时,为了访问父类的成员,必须使用super。 如果没有重名,使用super、this、直接访问都可。
package Extends;
public class A {
public static void main(String[] args) {
C c = new C();
c.say();
}
}
class B{
public void say(){
System.out.println("B");
}
}
class C extends B{
public void say(){
System.out.println("C");
super.say();
//
this.say();
//
say();
}
}
C
B
this表示当前对象,super表示子类中访问父类对象。
this访问和调用都是先从本类开始,super直接访问父类中的属性和方法。
五、方法重写
子类的方法和父类的方法的名称、返回类型、参数一样,称为子类的方法覆盖了父类的方法。(构成覆盖关系)
● 子类方法的名称、参数要和父类方法的名称、参数完全一致。
● 子类方法的返类型和父类方法的返回类型一致,或者是父类返回类型的子类。
● 子类方法不能缩小父类方法的访问权限(public>protected>默认>private)
六、多态
多态:使用一个变量去调用函数,前提是两个类(对象)存在继承关系。
package Extends;
public class A {
public static void main(String[] args) {
C c = new C();
System.out.println(c.sum(10,20));
System.out.println(c.sum(10,20,30));
B b = new B();
b.say();
c.say();
}
}
class B{
public void say(){
System.out.println("B");
}
}
class C extends B{
public int sum(int n1,int n2){
return n1 + n2;
}
public int sum(int n1,int n2,int n3){
return n1 + n2 + n3;
}
public void say(){
System.out.println("C");
}
}
java的对象变量是多态的,能保存不止一种类型的对象(声明类型的对象或者声明类型的子类的对象)。
一个对象的编译类型和运行类型可以不一致,编译类型在定义对象时确定(无法改变),运行类型可以改变。(编译类型看 = 左边,运行类型看 = 右边)
向上转型: 把子类的对象当作父类的对象,向上转型是默认的,不需要运算符,总是安全的。
父类类型 应用名 = new 子类类型();
可以调用父类中的所有成员(遵守访问权限),不能调用子类中的特有成员。
向下造型:子类类型 引用名 = (子类类型) 父类引用;
只能强转父类的引用,不能强转父类的对象,父类的引用必须指向的是当前目标类型的对象。向下造型后,可以调用子类类型中的所有成员。
属性的值看编译类型(instanceof比较操作符,判断对象的运行类型是否为XX类型或者其子类型)
package Extends;
public class Extends {
public static void main(String[] args) {
Base base = new Base();
Sub sub = new Sub();
Object object = null;
System.out.println(sub instanceof Sub);
System.out.println(object instanceof Base);
Base base = new Sub();
System.out.println(base instanceof Base);
System.out.println(base instanceof Sub);
}
}
class Base{
int count = 10;
}
class Sub extends Base{
int count = 20;
}
true
false
true
true
七、绑定机制
当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定;调用对象属性时,没有动态绑定机制,哪里声明哪里调用。
函数调用的绑定: 通过对象变量调用函数,调用哪个函数的这件事叫做绑定。
静态绑定: 变量的声明类型决定
动态绑定: 变量的动态类型决定(默认使用)
八、Object类
Object类:所有的类都是继承自Object类。
equals方法
==:判断基本类型和引用类型,基本类型判断值是否相等,引用类型判断地址是否相等。
equals:只能判断引用类型,在Object类的子类中往往重写该方法用于判断内容是否相等(Integer、String)
public boolean equals(Object obj) {
return (this == obj);
}
static final boolean COMPACT_STRINGS;
private final byte coder;
private final byte[] value;
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
return (anObject instanceof String aString)
&& (!COMPACT_STRINGS || this.coder == aString.coder)
&& StringLatin1.equals(value, aString.value);
}
public static boolean equals(byte[] value, byte[] other) {
if (value.length == other.length) {
for (int i = 0; i < value.length; i++) {
if (value[i] != other[i]) {
return false;
}
}
return true;
}
return false;
}
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
hashCode方法
提高具有哈希结构的容器的效率,两个引用如果指向的是同一个对象,哈希值是一样的,哈希值主要是根据地址号来但不能完全等价。如果有需要也可以对hashCode进行重写。
toString方法
返回全类名@哈希值的十六进制,子类会重写方法用于返回对象的属性信息,当直接输出一个对象时,会被默认调用。
public final native Class<?> getClass();
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
private transient String name;
private native String initClassName();
public String getName() {
String name = this.name;
return name != null ? name : initClassName();
}
public class Extends {
public static void main(String[] args) {
Base base = new Sub();
System.out.println(base);
System.out.println(base.toString());
}
}
Extends.Sub@7ef20235
Extends.Sub@7ef20235
finalize方法
-
当对象被回收时,系统自动调用该对象的finalize方法,子类可以重写该方法做一些释放资源的操作。
-
当一个对象没有任何引用时,就会使用垃圾回收机制来销毁该对象,在销毁前先调用finalize方法。
-
垃圾回收机制的调用是由系统决定,可以通过System.gc()主动触发。
package Extends;
public class Extends {
public static void main(String[] args) {
Base base = new Base(20);
base = null;
System.gc();
}
}
class Base{
int count = 10;
public Base(int count) {
this.count = count;
}
@Override
protected void finalize() throws Throwable {
System.out.println("finalize");
}
}
finalize
最后
以上就是鲤鱼紫菜为你收集整理的Java学习笔记(二):封装、继承、多态一、访问修饰符二、封装三、继承四、super关键字五、方法重写六、多态七、绑定机制八、Object类的全部内容,希望文章能够帮你解决Java学习笔记(二):封装、继承、多态一、访问修饰符二、封装三、继承四、super关键字五、方法重写六、多态七、绑定机制八、Object类所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复