(java学习笔记)JavaSE面向对象

总:学习面向对象内容的三条主线

​ 1.Java类及类的成员 :属性 方法 构造器;代码块 内部类

​ 2.面向对象的三大特征 :封装 继承 多态

​ 3.其它关键字 this super static final abstract interface package import…

JavaSE面向对象

一、面向对象的两个要素

1.类(Class)

定义: 构造对象的模板,是一类具有共同特征的事物的抽象。
Java代码基本上都是由类构成的(还有接口)

2.对象(Object)

定义: 是由类创建,实际存在的该类事物的每个个体,因而也称为实例(instance)。
对象是面向对象程序设计的基本单元,是类的一个实例。

由类构造(construct)对象的过程称为创建类的实例,即 类的实例化

3.Java类及类的成员

设计类即设计类的成员(属性+行为)

1.1、类的语法格式

修饰符 class 类名{

​ 属性声明;

​ 方法声明;

}

常用的权限修饰符

private、public、缺省、protected

1.2、 类中属性的使用

属性 = 成员变量 = Field = 域

1.21、属性(成员变量)vs 局部变量

不同点

​ 1.在类中声明的位置不同
​ 属性:直接定义在类的一对{}中,
​ 局部变量:声明在方法内、方法形参内、代码块内、构造器形参、构造期内
​ 2关于权限修饰符的不同.
​ 属性:可以在声明时,指明其权限,使用权限修饰符
​ 局部变量:不可以使用权限修饰符
​ 3.关于默认初始化值的不同
​ 属性:类的属性,都有其默认的初始化值
​ 整型(byte、short、int、long):0
​ 浮点型(float、double):0.0
​ 字符型(char):0/ ‘\u0000’
​ B布尔型(boolean):false
​ 引用数据类型(类、数组、接口):null
​ 局部变量:没有默认初始化值
​ 4.在内存中加载的位置不同
​ 属性:加载到堆空间中
​ 局部变量:加载到栈空间中(非static 型)

相同点

​ 变量都有其对应的作用域,一旦超出,就失效了

1.3、方法

(Java中)方法 = 函数(c…中) = Method
方法:描述类应该具有的功能
例:Math类中有 sqrt()、random()…
Scanner类中有nextXXX()…
Arrays类中有sort()、binarySearch()、toString()、equals()…

类中方法的使用:

1.31、方法的声明格式

修饰符 返回值类型 方法名(参数类型 参数一,参数类型 参数二…){

​ 方法体(程序代码);

​ return 返回值;

}

1.32、方法的分类

在这里插入图片描述
​ 方法中只能调用方法或属性,不可以在方法内部定义方法。

1.33、方法的重载(overload)

重载:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
同一个类,相同方法名,参数列表不同

​ 特点:与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别

1.34、可变个数的形参( Varargs 机制)

​ 定义: 允许直接定义能和多个实参相匹配的形参

  1. 格式:方法名(数据类型名 ...参数名)
    
  2. 可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个或多个
  3. 可变个数形参的方法与同名的方法之间,彼此构成重载
  4. 可变参数方法的使用与方法参数部分使用数组是一致的
  5. 方法的参数部分有可变形参,需要放在形参声明的最后
  6. 在一个方法的形参位置,最多只能声明一个可变个数形参

1.35、(方法参数的)值传递机制

形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参

1.4、匿名对象的使用

定义:没有显式的赋值给一个变量名,只能调用一次。
例:new student().number

二、封装性(封装与隐藏)

​ 定义:隐藏对象内部的复杂性,只对外公开简单的接口。
​ 体现:①(属性私有化,方法公开化)
​ ②(不对外暴露的私有的方法)
​ …
原则:将对象的内部结构对外做信息隐藏,让外部不可访问,但提供一系列的公有接口,用来与其他对象进行消息传递。

属性私有化

private int age;

方法公有化:( 提供关于属性XXX的get和set方法,并公有化)

public int getAge(){
        return age;
}
public void setAge(int a){
        age = a;
}

四种访问权限修饰符
在这里插入图片描述

对于class的权限修饰只可以用public和default(缺省)。
public类可以在任意地方被访问。
default类只可以被同一个包内部的类访问。

三、构造器(构造方法、constructor)

构造器的作用:创建对象;给对象(的属性)进行初始化

例:

Order o = new Order(); 

Person p = new Person(“Peter”,15);

​ 语法格式:权限修饰符 类名 (参数列表)
​ {
​ 初始化语句;
​ }

1、分类

隐式无参构造器(系统默认提供)

显式定义一个或多个构造器(无参、有参)

2、特征

①它具有与类相同的名称

②它不声明返回值类型。(与声明为void不同)

③不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值。

④Java语言中,每个类都至少有一个构造器

⑤默认构造器的修饰符与所属类的修饰符一致

⑥一旦显式定义了构造器,则系统不再提供默认的空参构造器

⑦一个类可以创建多个重载的构造器

⑧父类的构造器不可被子类继承

2.1、赋值的位置

① 默认初始化
② 显式初始化
③ 构造器中初始化
④ 通过“对象.属性“或“对象.方法”的方式赋值
赋值的先后顺序: ① - ② - ③ - ④

四、关键字—this package import

使用情景:①区分属性和局部变量(形参)。:当形参和属性重名时

1、this

this 可以调用类的 属性,方法,构造器。
this 调用属性、方法时(当形参和属性重名时)理解为当前对象的 (属性或方法)
this 调用构造器 this():(在另一个构造器中)调用空参构造器
this(age):调用 public Person(int age){} 构造器不能自己调用自己(构造器)
this(形参列表) 必须声明在构造器的首行

2、package

package :用来声明类或接口所属的包,声明在源文件的首行。

​使用小写字符标识
同一个包下,不能命名同名的接口或类。不同的包下可以命名。

3、import

import :导入

​在源文件中显示的使用import关键字导入指定包下的类或接口,声明在package下
在这里插入图片描述

使用java.lang包下定义的类或接口,可以省略导入。
使用本包下定义的,也可以省略导入。
import static:导入指定类或接口的静态结构。

五、继承性(Inheritance)

​ 关键字 extends

​ 语法格式:class A extends B{}
(A:子类、派生类、subclass B:父类、超类、基类、superclass)

作用: ①继承的出现减少了代码冗余,提高了代码的复用性。
②继承的出现,更有利于功能的扩展。
③继承的出现让类与类之间产生了关系,提供了多态的前提。

规则:①子类不能直接访问父类中私有的(private)的成员变量和方法。(子类能够获取父类中私有的属性和方法,但不能直接访问)
②Java只支持单继承和多层继承,不允许多重继承( 一个子类只能有一个父类,一个父类可以派生出多个子类)
③所有的Java类(除Object类)都直接或间接的继承于java.lang.Object类。

1、重写( override/overwrite )

定义:在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行

时,子类的方法将覆盖父类的方法。

​ 要求:1、子类重写的方法必须和父类被重写的方法具有相同的方法名称、参数列表

​ 2.①父类被重写的方法的返回值类型是void,子类重写的方法的返回值类型必须是void

​ ②父类被重写的方法的返回值类型是A类,子类重写的方法的返回值类型可以是A类或A的子类

​ ③父类被重写的方法的返回值类型是基本数据类型,子类重写的方法的返回值类型必须是相同的基本数据类型

​ 3.子类重写的方法使用的访问权限不能小于父类被重写的方法的访问权限
(子类不能重写父类中声明为private权限的方法 )
​ 4.子类方法抛出的异常类型不能大于父类被重写方法的异常类型

注意:子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为 static的(不是

重写)。因为static方法是属于类的,子类无法覆盖父类的方法。

2、关键字:Super

​ 在Java类中使用super来调用父类中的指定操作:

​ ①super可用于访问父类中定义的属性
​ ②super可用于调用父类中定义的成员方法
​ ③super可用于在子类构造器中调用父类的构造器
​ (1.子类中所有的构造器默认都会访问父类中空参数的构造器)
​ (2.当父类中没有空参数的构造器时,子类的构造器必须通过this(参数列表)或者super(参数列表)语句指定调用本类或者父类中相应的构造器。同时,只能”二选一” ,且必须放在构造器的首行)
​ (3.如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有无参的构造器,则编译出错)

当子父类出现同名成员时,可以用super表明调用的是父类中的成员

this(形参列表):调用本类重载的其它构造器
super(形参列表):调用父类中指定的构造器
默认 super(空参)

3、子类对象实例化过程

​ 当我们通过子类的构造器创建子类的对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器…直到调用了Java.lang.Object类的空参构造器为止。

六、多态性

1、对象的多态性:父类的引用指向子类的对象

​ 例:Person p = new Student();
多态的使用:(虚拟方法调用)
​ 当调用父类(虚拟方法)同名同参数的方法时,实际执行的是子类重写父类的方法。

编译时,看左边;运行时,看右边。
Java引用变量有两个类型:编译时类型和运行时类型。
编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。

多态的使用前提:①类的继承关系 ②方法的重写

对象的多态性只适用于方法,不适应于属性(编译和运行都看左边)

2、虚拟方法调用

子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。(多态性是运行性行为,不是编译时行为。)
虚拟方法调用的过程也称为动态绑定

3、重载与重写(多态)

3.1、重载

编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法, 这称为“早绑定”或“静态绑定”。

3.2、多态

对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“向下转型”。

有了对象的多态性后,内存中实际上是加载了子类中所特有的属性和方法的,但是由于变量类型声明为父类类型,导致编译时,只能调用父类中声明的属性和方法,子类所特有的属性和方法不能调用。

4、如何调用子类中所特有的属性和方法?

向下转型:使用强制类型转换符
Person p1 = new Man();
例:Man m1 = (Man)p1;
在这里插入图片描述
使用强转时,可能会出现ClassCastException的异常。

为了避免在向下转型时该异常的发生,引出instanceof关键字,先进行判断。

x instanceof A:检验对象x是否为类A的实例化对象,返回值为boolean型。
如果x instanceof A 返回true ,x instanceof B 也返回true。则类B是类A的父类

4.1、Object类的使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OqPGiR5L-1585963918401)(JavaSE面向对象.assets/Object类.png)]

4.2、== 和 equals的区别

  1. == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址
  2. equals的话,它是属于java.lang.Object类里面的方法,如果该方法没有被重写过默认也是==;我们可以看到String等类的equals方法是被重写过的,而且String类在日常开发中用的比较多,久而久之,形成了equals是比较值的错误观点。
  3. 具体要看自定义类里有没有重写Object的equals方法来判断。
  4. 通常情况下,重写equals方法,会比较类中的相应属性是否都相等。

4.3、 toString()方法

​ toString()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址。
​ String、Date、File、包装类等方法都重写了Objest类中的toString()方法,使得在调用对象的toString()方法时,返回实体内容信息。

5、Java中的JUnit单元测试

步骤

  1. 选中当前工程 - 右键 build path - add libraries - Junit 4 - 下一步
  2. 创建一个Java类进行单元测试

此Java类要求:①:此类是public的
②:此类提供一个公共的无参的构造器。

  1. 在此类中声明单元测试方法 此时的单元测试方法要求:方法的权限是public,无返回值,无形参。

  2. 此单元测试方法上需要声明注解:@Test ,并在单元测试类中导入import org.junit.Test

  3. 在方法体内测试相关的代码,后执行:左键双击单元测试方法名,右键:run as - Junit Test。

6、包装类(Wrapper)的的使用

针对八种基本数据类型定义相应的引用类型—包装类(封装类)
在这里插入图片描述
基本数据类型、包装类与String类间的转换
基本数据类型–>包装类 :调用对应包装类的构造器
包装类–>基本数据类型:调用对应包装类的xxxValue()
自动装箱:基本数据类型–>包装类
int num1 = 12; Integer in1 = num1;
自动拆箱: 基本数据类型–>包装类
int num2 = in1;
基本数据类型、包装类 --> String类型
方式①:连接运算
int num1 = 12; String str1 = num1 + “”;
方式②:调用String的valueOf(Xxx xxx)
float f1 = 12.3f; String str2 = String.valueOf(f1);
Double d1 = 123.2;String str3 = String.valueOf(d1);
String类型 -->基本数据类型、包装类:调用包装类的parseXxx(String s)
String str1 = “123”;int num1 = Integer.parseInt(str1);

7、static关键字

static可以修饰 属性、方法、内部类、代码块。

使用static修饰的属性:静态变量(类变量) 非static修饰的属性:实例变量

实例变量归具体的某一个对象所有

类变量是随着类的加载而加载。可以通过类.属性 调用该变量

静态变量的加载要早于对象的创建

类只会加载一次,所以类变量也只会加载一次

使用static修饰的方法:静态方法 vs 非静态方法

静态方法随着类的加载而加载

静态方法中只能调用静态的方法或属性(不能使用this super关键字)

非静态方法中都可以调用

8、单例设计模式

采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法

饿汉式:1.私有化构造器->使其不能在main()中调用,即不可以直接创建类的对象

​ 2.内部创建静态的类的对象,并初始化

​ 3.提供公共的静态的方法,返回类的对象。

懒汉式:1.私有化构造器

​ 2.声明当前静态的类的对象,没有初始化

​ 3.提供公共的静态的方法,返回当前类的对象。

9、代码块(Block) 初始化块

用来初始化类、对象,内部可以有输出语句

9.1、静态代码块

static{
}

随着类的加载而执行,只执行一次

作用:初始化当前类的信息进行初始化
如果一个类中定义了多个(非)静态代码块,按其声明的顺序执行

9.2、非静态代码块

{
}
随着对象的创建而执行,每创建一个对象就执行一次
作用:可以在创建对象时,对对象的属性等进行初始化

由父及子 静态先行

10、final关键字

final 可用来修饰 类、方法、变量

final修饰一个类:该类无法被其他类所继承 例:String类、System类

final修饰一个方法:此方法不可以被重写 Object类中的getClass()

final修饰一个变量:此变量不能在被赋值,被称为常量(大写)

​ final修饰一个属性:可以考虑赋值的位置:显示初始化,代码块中初始化、构造器中初始化

​ final修饰局部变量:final修饰形参时,表明此形参是一个常量

static final修饰一个属性,被称为全局常量

11、抽象类与抽象方法 abstract

抽象方法:只有方法的声明,没有方法的实现。以分号结束:比如:public abstract void talk();
抽象方法必须在子类中重写或子类必须是抽象类

抽象类:不能被实例化。抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类。

含有抽象方法的类必须被声明为抽象类
子类重写了所有的父类的抽象方法,此子类才可以实例化。

不能用abstract修饰变量、代码块、构造器;
不能用abstract修饰私有方法、静态方法、final的方法、final的类。

抽象类的匿名子类;创建匿名子类的对象

模板方法设计模式:当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以 把不确定的部分暴露出去,让子类去实现。

七、接口(interface)

JAVA语言中,接口与类是并列的两种结构

1、如何定义接口中的成员:

jdk7及以前:只能定义全局常量和抽象方法
>全局常量:public static final…(书写时可以省略)
>抽象方法:public abstract…(书写也可以省略)
jdk8:除了能定义全局变量和抽象方法之外,还可以定义静态方法、默认方法

2、接口中不能定义构造器,即接口无法实例化

java开发中,接口通常让类去实现(implements)的方式来使用
如果实现类覆盖了接口中的所有抽象方法,则此实现类可以实例化
如果没有,就必须定义为抽象类
java类可以实现多个接口 >> 弥补了java单继承性的局限性

先写extends,后写implements
接口也可以继承其它接口,具有多继承性

接口的具体使用,体现了多态性(与继承关系类似,接口与实现类之间存在多态性)

3、面向接口编程:接口的主要用途就是被实现类实现。

八、内部类(Inner class)

在java中允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。

分类:成员内部类(静态、非静态) vs 局部内部类(方法内、构造器内、代码块内)

成员内部类(static成员内部类和非static成员内部类)
局部内部类(不谈修饰符)、匿名内部类

全局变量和抽象方法之外,还可以定义静态方法、默认方法

接口中不能定义构造器,即接口无法实例化
java开发中,接口通常让类去实现(implements)的方式来使用
如果实现类覆盖了接口中的所有抽象方法,则此实现类可以实例化
如果没有,就必须定义为抽象类
java类可以实现多个接口 >> 弥补了java单继承性的局限性

先写extends,后写implements
接口也可以继承其它接口,具有多继承性
引用于尚硅谷

注:本文章是根据哔哩哔哩公开课 Java -Java 学习- Java 基础到高级-宋红康-零基础自学Java-尚硅谷 整理所得
大爱康师傅!!

发布了8 篇原创文章 · 获赞 0 · 访问量 165

猜你喜欢

转载自blog.csdn.net/qq_43110389/article/details/105305909