第六章:面型对象

在Java中面向对象是非常重要的,要将概念和代码结合起来,理解面向对象的概念。

第六章:面向对象

1抽象数据类型

1.1面向对象基本概念

1.1.1面向对象

​ 面向对象:面向对象编程(OOP)则是一种以对象为中心的编程方法。在面向对象编程中,问题被看作是一系列相互作用的对象,每个对象都有自己的状态和行为,并且可以通过定义对象的类来创建和管理对象。面向对象的编程语言有Java、C++和Python等。

​ 面向对象有三大特征:封装,继承,多态

tips: 面向过程:面向过程是一种基于步骤和过程的编程范式,它将问题看作是一系列的步骤和函数,通过依次执行这些步骤来解决问题。在面向过程编程中,重点放在了处理数据和执行操作,函数是模块化的基本单位。常见的面向过程编程语言有C和Pascal。

OOP与POP的区别

​ 面向对象编程(OOP)和面向过程编程(POP)是两种不同的编程范式,它们在如何组织和管理程序的结构方面有着明显的区别。

面向过程编程(POP):

  • 关注问题的解决过程,通过将问题拆分成一系列的步骤和函数来实现。
  • 程序的组织结构是基于功能模块的,通过一系列的函数调用来完成任务。
  • 以过程或函数为中心,数据和函数是分离的,数据在函数之间传递。
  • 基于顺序执行,通过控制流(如条件语句和循环)来实现程序的控制。
  • 着重于算法和逻辑的实现,更直接、简单。

面向对象编程(OOP):

  • 关注问题的解决方案,通过创建对象来实现这些解决方案。
  • 程序的组织结构是基于对象的,对象包括数据和相关的操作(方法)。
  • 将数据和可对其执行的操作封装在一起,形成类和对象的层次结构。
  • 通过类的继承、封装和多态等概念来实现代码的重用和灵活性。
  • 更注重代码的可扩展性和可维护性,更适合大型项目。

​ 面向过程和面向对象各有其优势和特点,选择使用哪种方法取决于问题的本质和设计的需求。面向过程适合简单的、线性的问题,而面向对象更适合复杂的、具有较高模块化和可重用性的问题。在实际开发中,也会根据具体情况采用面向过程和面向对象相结合的方式来编写程序。

1.1.2对象

​ 对象:具体的某一个事物,在面向对象中,万物皆可对象。对象时类的实例

1.1.3类

​ 类:拥有相同特征和行为的对象抽象成类。类是对象的抽象,是一类事物的集合和抽象,代表着这类事物所共有的字段和行为。

1.1.4类和对象的区别

​ 类是抽象的,对象是具体的,类是具有相同特征的对象抽象而成,而对象是类实例化产生的

1.2定义类

​ 类是由字段和方法两部分构成的

  • 发现类,类定义了对象将会拥有的特性(字段)和行为(方法)
  • 发现类的字段,对象所拥有的特性在类汇总的表现为类的字段
  • 发现类的方法,对象执行的操作成为类的方法
1.2.1定义类

	创建类:[类的修饰符] class 类名{ 
    	//classBody	可以有  类的成员,静态初始化,实例初始化
    }  

1.2.2类的字段与方法

​ 类的组成:字段和方法

​ 字段:对象所拥有的特征在类中表示为类的字段,字段使用变量来表示。

[访问修饰符] 数据类型 字段名;

​ 方法:对象执行的操作称为类的方法。

[访问修饰符] 返回值类型 方法名(形式参数(参数类型 参数名)) 

特征:字段(属性、变量)

​ 有static的方法属于类,叫做类方法,用类名.方法名[实参列表]来调用,没有static的属于对象,叫做实例方法(instance-method)。用对象.方法[实参列表]来调用,无论有无static都是成员方法,都是类的成员

​ 成员变量:在类中(方法外)声明的变量

下面是一个例子:

​ 特征——人:姓名,性别,年龄;吃饭,睡觉

//字段
public class Person
    String name;
char gender;
int age;
//方法
public void eat(String food){
    System.out.println("吃了"+food);
}
public void sleep(){
    System.out.println("睡觉");
}

​ 有类之后才可以创建对象

new Person();
Person().sleep;
//输出睡觉

//实例化Person为p
Person p = new Person();

1.3创建和使用对象

1.3.1创建对象

​ 一个对象成为类的一个实例,是类一次实例化的结果。

类名 对象名 = new 类名()
1.3.2使用对象

​ 在Java中,要引用对象的字段和方法,需要使用成员运算符“.”的方式使用。

class People {
    //类的属性
    String name;
    int age;
    //类的构造方法
    People(String name,int age){
        this.name=name;
        this.age=age;
    }
    //类的方法
    public void run(){
        System.out.println("跑");
    }
}
class Test{
     //主函数
    public static void main (String[] args){
        People peoson = new People("张三",20);
        peoson.run();
        //输出跑
    }
}

2.对象的构造和初始化

​ 调用构造方法时:

(1)分配新对象的空间,并进行默认的初始化。在Java中,这两步是不可分的,从而可确保不会有没有初值的对象。

(2)执行显示的成员初始化

(3)执行构造方法,构造方法时一个特殊的方法

2.1成员变量

2.1.1成员变量的作用域

​ 类中的字段是直接定义在类的内部,方法的外部的变量,称为作用变量。(成员变量的作用域是整个类)

2.1.2显示成员初始化

​ 显示成员:(Expliit Members)是指在编程语言中,使用直接的方式来访问或者调用类或对象的成员,包括属性,方法,字段。

2.1.3局部变量的作用域

​ 局部变量:定义在方法内部的变量,局部变量只能在方法内部使用。

2.1.4成员变量与局部变量的区别

​ 作用域不同:局部变量的作用域仅限定于定义它的方法,在该方法外无法被访问。成员变量的作用域是在整个类内,所有的成员方法都可以使用它。

​ 初始值不同:对于成员变量如果没有定义初始值那么系统将会给予它一个默认值。对于局部变量来说系统不会将给予,因此必须需要给局部变量一个初始值(否则将会出现编译报错)。

2.1.5按值传递

​ 在Java中,方法调用采取值传递的方式。参数是在方法定义中声明的变量,用于接受传递给方法的值,而实参则是在方法调用时传递给方法的具体值。

​ 换句话说:当对象实例作为参数传递给方法时,实际传递的是对象引用的副本,也就是说,在方法中修改参数,并不会导致参数的引用指向指向别的地方,但是可以对参数进行值的修改。

2.2构造方法

​ 在Java中,当创建一个类的对象时,会自动调用该类的构造方法。构造方法分为默认构造方法和自定义构造方法。

​ 构造方法是一种特殊的实例方法,具有特殊的功能。它的名称与类名相同,没有返回值,并且在使用new关键字创建对象实例时会自动调用。

2.2.1构造方法的定义
[访问修饰符] 方法名([参数列表]){
    //省略方法体的代码
}
2.2.2默认构造方法

​ 每个类都必须至少有一个构造方法。如果没有为类定义构造方法,系统会自动为该类生成一个默认的构造方法。(构造方法的参数列表,方法体均为空;所生成的对象的属性值也为0或空)如果定义了一个或者多个构造方法,则将自动屏蔽掉默认的构造方法

特别的构造方法不可用用于继承

2.2.3方法重载

​ 定义:方法重载是指在一个类中定义了多个拥有相同名称的方法,但要求每个方法具有不同的参数(类型,顺序,数量)。

​ 特点:在同一个类中,参数的个数或者类型或者顺序不同,方法的返回值不能作为方法是否重载的依据。

​ 重载方法的调用:方法重载在调用时,根据实参与形参的类型,顺序,个数一 一进行匹配的规则调用。

​ 方法重载的优点:方法重载其实是对原有方法的一种升级,可以根据参数的不同,采用不同的实现方法,而且不需要编写多个名称,简化了调用方法的代码。

public class Person{
    public String name ;
    public String gender;
    public int age;
    
    public void work(){
        System.out.println(this.name + "人很好");
    }
    public void work(String content){
        System.out.println(this.name + "人很好"+ content);
    }
    
    public static void main (string[] args){
        Person p = new Person();
        p.name = "张三";
        p.gender = "男";
        p.age = 20;
        
       	p.work();
        //张三人很好
        p.work("ta很善良")
        //张三人很好ta很善良
    }
}
2.2.4构造方法的重载

​ 对于构造方法来说也是可以重载的:总结来说就是对于所有方法来说都是可以进行重载的但是除了有特殊修饰的方法

在这里需要对this与super进行介绍

this:

​ 使用this的目的在于解决成员变量与局部变量之间的同名冲突问题,使用this调用重载的构造方法时,只能在构造方法中使用,且必须是构造方法的第一句语句,this不能调用this写在的构造方法的自身。

​ 注意:因为this是在对象内部代表自身的引用,因此this只能调用实例变量,实例方法和构造方法,不能调用类变量,也不能调用局部变量

this
调用方法this访问的本类中的方法,包括从父类中继承的方法
调用构造方法this(【参数列表】)表示调用本类的构造方法,必须放在构造方法的首行
调用字段this.字段——调用的当前对象的字段,包括从父类继承的字段
使用this在实例方法中可以使用,在static方法中不能使用,只能出现在子类中
其他区别this表示当前对象
特别的使用this调用其他构造方法:this[实参列表]调用重载的构造,只能调用构造的第一行出现

super:

​ 1.创建子类对象时需要先创建父类对象,默认在构造方法的第一行调用父类的无参构造,调用代码可以省略。

​ 如果父类没有无参构造,则需要在每一个构造方法的第一行通过super关键字调用父类的构造

​ super表示父类对象,super([参数列表]),表示调用父类的构造方法。{必须第一行}

​ 2.在子类中想要调用父类可见的成员可以通过super.成员的方式调用

public Cat(String name){
	super(name,"猫科动物")
}

​ 注意:this与super不能同时作为调用构造方法,this与super不能同时使用

public Cat(){
	this(name,"猫科动物");
	//super(name,"猫科动物");
}
super
调用方法super访问父类的方法
调用构造方法super(【参数列表】)表示调用父类构造,必须放在子类构造方法首行。如果调用父类的无参构造super()可省略
调用字段super.字段调用的是父类中的字段
使用super在实例方法中可以使用,在static方法中无法使用,只能出现在子类中
其他区别super不能表示当前对象

this与super的区别

​ 1.this表⽰当前对象,super指代⽗类对象。

​ 2.this可以解决变量遮蔽问题,super可以解决隐藏问题。

​ 3.this调⽤属性或⽅法时,本类没有可以调⽤⽗类的;super调⽤⽗类的属性或⽅法。

​ 4.this可以在任何类中使⽤,super出现在⼦类中。

​ 5.都只能在实例⽅法、构造⽅法或实例初始化器中使⽤。

​ 6.都可以表⽰构造⽅法的调⽤,并且只能在构造⽅法第⼀⾏,不能同时出现。如果⼦类构造中调⽤⽗类⽆参构造 ⽅法时,此时 super() 可以省略。

2.2.5对象数组

​ 数组是相同类型的一组数据,对象数组:(Object Arrays)是指存储对象引用的数组,其中的每个元素都可以指向一个特定类型的对象。在Java中,我们可以创建对象数组来存储同一类型的对象。对象数组的声明和初始化方式与普通数组类似,只是在声明时需要使用对象类型而不是基本数据类型。

3包的使用

3.1包的概述

​ (1)包时类的容器,利用包来划分名字空间,用于分隔类名空间,以免类名冲突

​ (2)包的作用:存放类,防止命名冲突,包允许在更广的范围内保护类、数据、方法。

3.2包的定义

package 包名;

4访问修饰符

4.1类和类成员的访问控制

public(公共的); protected(受保护的) ;private(私有的)

​ 有四种权限:public protected private (不写)——就是包的访问修饰符,包可以访问就可以访问

位置publicprotected包的访问修饰符private
同类访问
同包其他类访问×
同包子类访问×
不同包子类访问××
不同包非子类访问×××

4.2Static关键字

4.2.1Static修饰属性

​ 使用static修饰的属性称为静态属性或者类变量,没有static修饰的属性称为实例变量,但是它们两个都属于是对象的属性。与这个概念相通的是用static修饰的方法与没有用static修饰的方法同样也是对象的方法。

​ 对于使用static修饰的方法或者属性都可以通过类名.的方式进行访问或者使用

注意:在静态方法中无法不能直接访问实例变量和实例方法;在实例方法中可以直接调用类中定义的静态方法或者静态属性(原因现有静态方法或者属性,而后拥有实例方法,因此在静态方法中无法直接调用实例方法和实例属性)

4.2.2Static修饰方法

​ 用Static修饰的方法称为静态方法或者类方法,不使用Static修饰的方法称为实例方法,对于类方法来说其不依赖于任何对象,用类名直接加“.”直接调用。

4.2.3静态初始化

​ 静态初始化代码块在类被加载的时候只执行一次,且只能访问类的静态变量和方法。

​ java中静态初始化是一种在类被加载时执行的初始化方式,用于初始化类的静态变量和执行一些静态代码块。

Static{
    //静态初始化代码块
}

4.3静态成员于实例成员的区别

​ 静态成员(Static Members)和实例成员(Instance Members)是在面向对象编程中的两种不同类型的成员,它们之间有以下区别:

  1. 装载时机:静态成员在类加载时被初始化,而实例成员在类的实例化时才会被初始化。
  2. 存储方式:静态成员被存储在静态存储区,而实例成员被存储在每个对象的实例中。
  3. 对对象的依赖性:静态成员不依赖于特定的对象实例,可以在没有对象实例的情况下被使用,而实例成员必须在对象实例化后才能被使用。
  4. 访问方式:可以直接通过类名来访问静态成员,而实例成员需要通过对象实例来访问。
  5. 共享性质:静态成员属于整个类,所有的对象共享同一个静态成员,而实例成员属于每个对象独立拥有,每个对象都有自己的实例成员。
  6. 生命周期:静态成员的生命周期与类的生命周期相同,它们在类加载时被初始化,在类卸载时被销毁。实例成员的生命周期与对象的生命周期相同,它们在对象被创建时被初始化,在对象被销毁时被销毁。

静态成员通常用于表示与类共享的属性和方法,例如静态变量和静态方法,它们可以在类的任何对象之间共享数据。实例成员则用于表示每个对象独有的属性和方法,每个对象可以拥有不同的实例成员值。

5封装

5.1封装描述

​ 封装是面向对象的三大特征之一,Java中的封装实际上就是将代码的细节隐藏在类的内部,不允许外部直接进行访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。

优点:

  • 防止外部直接访问类的内部数据,可以保护数据的安全性
  • 通过限制访问,可以更好控制数据的安全性和完整性
  • 可以隐藏类的实现细节,使类的用户不需要了解类的内部细节,只需要知道如何使用类提供的接口

5.4遮蔽

​ shadowing:在外部作用域中存在一个与内部作用域相同名称的变量,导致内部变量遮蔽了外部变量,使外部变量无法被访问到就是遮蔽

​ 遮蔽(shadowing):在内部作用域中声明一个与外部作用域中已有的变量具有相同名称的新变量,从而让外部作用域中的变量的无法被直接访问到。当在内部作用域中声明一个与外部作用域同名的变量时,使用该变量名引用时,实际上引用的是内部作用域的变量,而不是外部作用域的变量

public class ShadowingExample {
    private int x = 5; // 外部作用域的变量

    public void printX() {
        int x = 10; // 内部作用域的变量,遮蔽了外部作用域的变量
        System.out.println("内部作用域的 x 值为:" + x);
    }

    public static void main(String[] args) {
        ShadowingExample example = new ShadowingExample();
        example.printX(); // 输出:内部作用域的 x 值为:10
        System.out.println("外部作用域的 x 值为:" + example.x); // 输出:外部作用域的 x 值为:5
    }
}

6继承

6.1继承的基本概念

​ 继承:新类可以再不增加自身代码的情况下,通过现有类中继承其属性和方法,来实现充实自身内容,这种现象就是继承。

​ 在Java中继承的一些基本观念:

  • 子类可以继承父类的非私有属性和方法
  • 子类可以添加自己的属性和方法
  • 子类的构造方法可以调用父类的构造方法
  • Object类是所有类的基类
  • Java中的类只支持单一继承(每个类只能有一个父类)
  • 子类可以成为其他类的父类,从而建立多级继承关系

6.2继承的应用

//人类
public class Person{
    private String name;
    private Integer age;
    private Character gender;


    public void setName(String name){
        this.name = name;
    }
    public void getName(String name){
        return = name;
    }

    public void setAge(String name){
        this.name = name;
    }
    public void getAge(String name){
        return = age;
    }


    public Person{
        this("wu",18,'男');
    }
    public Person(String name,int age ,char gender){
        setName(name);
        setAge(age);
        setGender(gender);
    }
    public void setGender(char gender){
        this.gender = gender;
    }
    public String showInfo(){
        return name+age+gender;
    }
}

// 继承:extends用于继承
// 要满足两个类之间存在关系,两个类要存在
// A extends B    a是子类/派生类,b是父类/基类
// 只要不是private修饰的都可以继承
// 构造是不能进行继承的
// 在Java中所有类只能继承单独继承(只存在一个父类,可以有多个子类),就是继承一个(直接继承的)还存在一种间接继承,java类如果没有extends去显示继承一个类,那么这个类继承了java.lang.object类,所以object类是所有类的父类。
// final表示最终的,被final修饰的类是不能有子类的,如果被final修饰的方法是不能被重写的,但是可以进行重载
public class Studen extends Person{
    private String id;//学号
    public void setId(String id){
        this.id = id;
    }
    public void getId(char gender){
        return id;
    }
// 返回值类型,方法名,参数列表相同于父类
// 方法的重写:两个继承关系中,同名同参同返回类型的方法称之为子类重写了父类的方法,也可以称为覆盖。
// 对于重写,调用的是重写后的方法
// 访问权限要相同或者变大。
// 对于方法来说其返回值要相同,是同一个类型的,可以存在继承关系
// 注解@override标识发生重写(只有重写才能写这个注解)注解与注释是不同的
    public String showInfo(){
        return name+age+gender+id;
    }
}

6.3使用继承和重写实现子类

​ (1)使用继承定义部门及子类

public class Child extends Parent{
    private String school;
    public Child(String school){
        this.school = school;
    }
    public void printSchool{
        System.out.println("School:" + school);
    }
}

​ (2)使用super关键字调用父类成员

​ 调用父类构造方法:super([实参列表])

​ 调用父类属性和方法:super.<父类字段名/方法名>

​ 当需要在子类中调用父类的构造方法时,可以使用super关键字调用。

​ (3)方法的重写(@Override)

​ 方法的重写是对于存在继承关系的两个类中拥有相同名称的,相同返回值的,相同传值的方法。其不同于方法的重载

​ (4)方法隐藏

​ 父类和子类用有相同名字的属性或者方法(方法隐藏只有一种形式,就是父类和子类存在签名相同的静态方法)时,父类的同 名的属性或者方法形式上看不见了,但是实际上还是存在的。

​ 子类中有和父类同名的变量,就会发生隐藏(hiding)

​ 子类变量可以隐藏父类变量,和static无关(四种)

变量名重复:在同一个作用域中定义了与已有变量同名的新变量。这将隐藏原始变量并创建一个新的同名变量。
实例变量隐藏:在子类中定义了一个与父类中同名的实例变量。这将隐藏父类的同名实例变量,并创建一个新的同名实例变量。
静态变量隐藏:在子类中定义了一个与父类中同名的静态变量。这将隐藏父类的同名静态变量,并创建一个新的同名静态变量。
静态方法隐藏:在子类中定义了一个与父类中静态方法签名相同的静态方法。这将隐藏父类的同名静态方法,并创建一个新的同名静态方法。

​ 子类中拥有static的方法和父类中拥有static的方法同名,子类方法会隐藏(hiding)父类方法

(5)final关键字

​ final修饰的变量:其修饰的变量称为常量,一旦被初始化,就无法被修改。常量必须在声明时或在构造函数中初始化。

​ final修饰的方法:其修饰的方法称为不可覆盖方法,子类无法重写该方法。

​ final是表示最终的,用final修饰的属性是常量,其不能再被修改;用final修饰的方法是无法被子类重写;final修饰的类是无法被继承的

(6)Object类

​ object类

java.lang.object类是所有类的父类,object类中的成员(都是public、protected、修饰的)

下面是几个常用的方法:

  1. equals(Object obj)

    • 用于比较两个对象是否相等。

    • 默认情况下,使用==运算符比较两个对象的引用是否相等,如果需要比较对象的内容是否相等,需要在自定义类中重写该方法。

      1.自反性(Reflexivity):
      自反性是指一个对象与自身比较时,应该返回true。
      即对于任意非空对象x,x.equals(x)应该返回true。
      这意味着对象与自身始终是相等的。
      
      2.对称性(Symmetry):
      对称性是指如果一个对象x与另一个对象y相等,那么对于对象y与对象x的比较应该返回true。即对于任意非空对象x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true。这意味着比较的结果不依赖于对象的顺序。
      
      3.传递性(Transitivity):
      传递性是指如果一个对象x与另一个对象y相等,另一个对象y与第三个对象z相等,那么对象x与第三个对象z也应该相等。即对于任意非空对象x、y和z,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)也应该返回true。
      
      4.一致性(Consistency):
      一致性是指如果两个对象在没有发生变化的情况下多次比较,那么它们的equals方法的返回结果应该保持一致。即对于任意非空对象x和y,在对象没有发生任何变化的情况下,多次调用x.equals(y)应该返回相同的结果。
      
      5.与null的比较:
      对于任意非空对象x,x.equals(null)应该返回false。对于任意非空对象x,如果x.equals(null)返回true,可能会导致在使用对象时产生错误。
      
  2. hashCode()

    • 返回对象的哈希码值。

    • 哈希码用于在哈希表等数据结构中确定对象的存储位置。

    • 通常在重写equals()方法时,也会重写hashCode()方法来保持一致性。

  3. toString()

    • 返回对象的字符串表示。

    • 默认情况下,返回的是类名、对象地址的字符串,但可以在自定义类中重写该方法,以返回自定义的字符串表示。

  4. getClass()

  5. clone()

    • 创建并返回对象的副本。
    • 需要实现Cloneable接口,并在自定义类中重写该方法才能使用。

[clone()应用例子]: JavaLangraueTest/Clong · anewshool/JavaTest - 码云 - 开源中国 (gitee.com)

7多态

7.1实现多态

​ (1)认识多态:其是一个特定类型的变量,可以引用不同类型的对象,并且能自动地调用引用的对象的方法。方法重写是多态的基础。多态意味着在一次方法调用中根据包含的对象的实际类型(即实际子类的对象)来决定应该调用哪个子类的方法,而不是由用来存储对象引用的变量的类型决定的。

​ (2)向上转型:子类向父类转换成为向上转型,

父类类型 引用变量名 = new 子类类型();

​ 多态就是说一个父类可以有多个子类,每个子类都重写了父类的方法,当父类引用调用方法时,父类引用指向哪个子类,就调用哪个子类的方法,形成了父类引用调用相同的方法名称时,有不同的输出形态。

​ (3)向下转型

​ 将一个指向子类对象的父类引用赋值给一个子类引用,即父类类型转换为子类类型,称为向下转型(必须进行强制类型转化)

子类类型 引用变量名 =(子类类型) 父类类型的引用变量

多态:多种形态,同一个方法会产生不同的效果,多态很常见,方法重写是多态的基础

  1. 父类类型的变量引用了一个子类对象,向上转型,此时,只能调用父类声明中的方法,子类扩展方法不能调用。
  2. 调用静态方法时,调用的是父类的方法
  3. 调用实例方法时,要看哪个对象调用的就是执行哪个方法
  4. 调用实例方法看等号右边,static方法看等号左边
  5. 重载也可以被称之为多态,是多态的变现形式,是在编译时多态,而重写是多态的基础,是在运行时多态

​ 多态(Polymorphism)是面向对象程序设计中的一个重要概念,它允许同一类型的对象可以表现出多种行为和形态。

​ 在多态中,同一个方法名可以在不同的类中有不同的实现,这些类可以是继承关系中的父类和子类,或者是实现同一个接口的多个类。当调用这个方法时,具体执行哪个类的实现取决于调用的对象类型。

多态的基础知识包括以下几个关键点:

  1. 继承(Inheritance):通过继承,子类可以继承父类的属性和方法。子类可以重写(override)父类的方法,提供自己特定的实现。

  2. 方法重写(Method Override):子类可以重写父类的方法,方法名和参数列表需保持一致。重写后,当对子类对象调用该方法时,将执行子类的实现而不是父类的实现。

  3. 方法重载(Method Overload):在同一个类中,可以定义多个方法名称相同但参数列表不同的方法。根据传入的参数类型和数量,编译器会自动选择匹配的方法。

  4. 接口(Interface):接口定义了一个协定,规定了某个类必须实现哪些方法。多个类可以实现同一个接口,提供自己特定的实现逻辑。

  5. 抽象类(Abstract Class):抽象类是一种不能被实例化的类,它可以包含抽象方法和普通方法。抽象方法只有方法签名没有具体实现,必须在继承的子类中实现。

  6. 动态绑定(Dynamic Binding):在运行时确定对象的真正类型,从而调用正确的方法实现。通过动态绑定,可以实现多态的特性。

多态提高了代码的灵活性和可扩展性,允许以统一的方式处理不同类型的对象。它是面向对象编程中的重要概念,使得代码更易于维护和扩展。

instanceof在向下转型前,为了确保可以强制类型转换为我们事先使用instanceof进行判断,instanceof在有继承的类之间使用

()

总结:

  1. 对象数组的使用

  2. 使用对象作为方法的参数

  3. 向上转型,自动转换(继承关系在)

  4. 向下转型,强制类型转换(instanceof)。 是同一个类型

    • instanceof 要有继承关系才能判断
    • 遵循的是大的向小的转化是需要进行强制转换的,而小的向大的转换时不需要进行类型的转换,例如这里有一个动物类,一个犬类,动物类包括犬类,而犬类并不完全指代动物类,也就是上面所说的大的向小的转化要强行转化,而小的向大的转化不需要进行强制转化。
  5. 多态

    • 什么是多态

      多态是通过一个方法,放在不同的对象上可以产生了不同的结果,例如通过一个打印方法,对于a对象来说,b对象可能打印出来了不同的东西,同样是通过打印这个方法进行打印,出来的东西却不同就是多态(我的描述可能更倾向于动态绑定)

      这里是更加准确一点的解释:多态性是指通过父类引用指向不同子类对象,并调用相同的方法时产生不同的行为。

    • 重写是基础,重写是运行时多态

    • 重载是编译时多态

  6. 在对象做为参数或返回值时有了更多的可能
    父类类型可以出现的地方,子类一定可以出现

本章中其他的知识点:


在Java中,类的初始化顺序遵循以下规则:

  1. 静态变量和静态初始化块:在类加载过程中,首先会执行静态变量的初始化和静态初始化块。静态变量只会被初始化一次,在类的整个生命周期中都会保持它们的值。
  2. 实例变量和初始化块:在对象实例化过程中,首先会执行实例变量的初始化和实例化块。每次创建实例时,都会重新执行实例变量的初始化,且在构造方法之前执行。
  3. 构造方法:最后会执行构造方法,用于完成对象的初始化工作。

综上所述,类的初始化过程是先执行静态变量和静态初始化块,然后在实例化时先执行实例变量的初始化和实例化块,最后执行构造方法。

局部变量与成员变量相同时,优先使用局部变量


自动拆箱和自动装箱

​ 自动拆箱和自动装箱是Java语言中的一种特性,用于自动转换基本类型和对应的包装类型。

​ 自动拆箱指的是将包装类型的对象自动转换为其对应的基本类型。例如,将Integer对象转换为int类型。

​ 自动装箱则是将基本类型的值自动转换为对应的包装类型的对象。例如,将int类型的值转换为Integer对象。

​ 这两种特性的存在主要是为了方便编程,让开发人员能够在基本类型和包装类型之间进行转换而不需要显式地进行类型转换操作。


​ 封装:它的主要目的是将数据(属性)和操作(方法)组合在一个单一的实体中,并对外部隐藏实现的细节。(有效控制,不能访问细节,更符合面向对象的特点)

​ 包装类:提供了很多对于基本数据类型的操作,最大值,最小值,数据转换等

Instanceof : 是一种用于检查对象类型的操作符。它用于确定一个对象是否是某个类的实例,或者是否实现了某个接口。


  • # 梳理
    1. this
    this:关键字this 表示在当前对象中(谁在调用(对象),this就是谁)
    
    2. 包
    - 包的作用
    控制访问权限,组织类和接口
    
    3. 访问修饰符
    - public
    公共的,同类,同包中不同类,不同包中子类,不同包中非子类都可以调用或者访问
    - protected
    受到保护的,在同类,同包中不同类,不同包中子类能访问或者调用它
    - private
    私有的,在只能同类中访问,其他地点无法进行访问或者调用
    - (不写) package-private/package-access
    依从包的访问修饰,包是什么访问修饰符,那么该类也是一样的
    1. 修饰类的访问修饰符
    2. 修饰成员、构造的访问修饰符
    
    
    4. 封装
    - 什么是封装
    封装是对代码的细节进行隐藏,提供给用户一个可以与细节进行互动的接口,但是用户接触不到细节
    - 为什么要封装
    目的:为了提高代码的可维护性、可重用性和安全性。
    - 如何封装
    通过使用访问修饰符控制可见性,将需要封装的类的成员用private修饰,后用公共方法进行调用或者修改。
    
    5. 包装类【了解】
    - 有哪些包装类
    包装类(Wrapper Class)是一种用于将基本数据类型包装为对象的类
    
    		以下是Java中常见的基本数据类型及其对应的包装类:
    				boolean 对应 Boolean
    				byte 对应 Byte
    				short 对应 Short
    				int 对应 Integer
    				long 对应 Long
    				float 对应 Float
    				double 对应 Double
    				char 对应 Character
    
    - 默认值是 null
    - 自动装箱、自动拆箱
    自动拆箱和自动装箱是Java语言中的一种特性,用于自动转换基本类型和对应的包装类型。
    
    6. 继承
    - 什么是继承
    允许一个子类继承一个父类,在继承后子类拥有父类中的属性和方法,也可以对自身进行改造,产生新的属性或者方法
    - 为什么要继承
    为的是减少冗余代码的出现,增加代码的复用性
    - 怎么继承
    通过extends关键字来进行继承(例如:class a extends b)即是类a继承于类b
    - 继承了什么
    可以继承可见的成员,不能继承private、构造、static初始化、实例初始化器是不能被继承的
    - 直接继承、间接继承
    直接继承是用于extends展示的类,而间接继承是继承了父类的父类,或者object类,都存在继承关系,但是一个是直接继承于,另一个是间接继承于。
    - 方法重写 (@Override)
    方法的重写是对于存在继承关系的两个类中拥有相同名称的,相同返回值的,相同传值的方法。其不同于方法的重载
    - instanceof 的使用
    instanceof表示属于返回值是boolean类型
    - Object是所有类的父类【了解】
    object类是所有类的父类或者称为基类,是Java中自带的一个类,不需要用extends进行表示,直接默认继承
    - final 的使用
    final是表示最终的,用final修饰的属性是常量,其不能再被修改;用final修饰的方法是无法被子类重写;final修饰的类是无法被继承的
    - 实例化的过程【大的顺序】
    总体顺序是先父类再子类,先进行对于静态代码块-》实例代码块-》构建代码块的顺序进行的,也就是说先加载父类静态代码块,再是子类静态代码块,后是父类,子类的实例代码块,最后是父类,子类的构建代码块(特别需要注意的是:父类的静态代码块只会在第一次加载父类时执行一次,子类的静态代码块只会在第一次加载子类时执行一次。而实例代码块和构造方法在每次创建实例时都会执行。)
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值