java面对对象编程--类、对象和类的组成

本文详细介绍了面向对象编程的核心概念,包括面对过程与面对对象的区别、类与对象的定义、属性与方法的声明与使用、构造器的作用、抽象类与抽象方法的特性,以及接口与内部类的使用。此外,还探讨了方法的重载与重写、参数传递、可变参数和代码块的细节,展示了如何通过这些机制实现代码的灵活性和可扩展性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 面对对象和面对过程

面对过程: 强调的是功能行为,以函数为最小单位,考虑怎么做。
面对对象: 将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
面对对象方法解决问题的思路和步骤:

  1. 根据问题需要,选择问题所针对的现实世界中的实体
  2. 从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类
  3. 把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。
  4. 将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。

2. 类和对象

:类是对一类事物的描述,是抽象的、概念上的定义。
对象:对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。
类实例化后就是具体的对象,举个栗子来说就是如果把人当成类的话,那么我们每一具体的人就是人这个类实例化后的对象,具体的你、我、他就是人这个类的对象。
类的声明和使用:
类声明的具体语法格式如下:

修饰符 class 类名 {
属性声明;
方法声明;
}

当我们要创建对象时,具体的语法: 类名 对象名 = new 类名();类的使用则通过使用“对象名.对象成员”的方式访问对象成员(包括属性和方法),但要注意不同类之间的访问方式的区别,在一个类中的方法可以直接访问类中的成员变量,但在不同类中,先创建要访问类的对象,再用对象访问类中定义的成员。

类对象的内存解析:
在这里插入图片描述
匿名对象:
创建的对象,没显式的赋给一个变量名,即为匿名对象。匿名对象一般在如下两种情况下使用:

  • 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
  • 我们经常将匿名对象作为实参传递给一个方法调用。

3. 类的组成成员

3.1 属性

语法格式:

修饰符 数据类型 属性名 = 初始化值 ;

  • 说明1: 修饰符
    常用的权限修饰符有:private、缺省、protected、public
    其他修饰符:static、final (暂不考虑)
  • 说明2:数据类型
    任何基本数据类型(如int、Boolean) 或 任何引用数据类型。
  • 说明3:属性名
    属于标识符,符合命名规则和规范即可。

属性和局部变量的区别:

在这里插入图片描述

3.2 方法

方法是类或对象行为特征的抽象,用来完成某个功能操作,在某些语言中也称为函数或过程,可以实现代码重用,简化代码,类中方法的声明格式为:

修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, ….){
方法体程序代码
return 返回值;

其中:
修饰符:public,缺省,private, protected等
返回值类型:

  • 没有返回值:void。
  • 有返回值,声明出返回值的类型。与方法体中“return 返回值”搭配使用方法名:属于标识符,命名时遵循标识符命名规则和规范,“见名知意”形参列表:可以包含零个,一个或多个参数。多个参数时,中间用“,”隔开返回值:方法在执行完毕后返还给调用它的程序的数据。

方法使用的注意点:

  1. 方法被调用一次,就会执行一次
  2. 没有具体返回值的情况,返回值类型用关键字void表示,那么方法体中可以不必使用return语句。如果使用,仅用来结束方法。
  3. 定义方法时,方法的结果应该返回给调用者,交由调用者处理。
  4. 方法中只能调用方法或属性,不可以在方法内部定义方法。

方法重载
所谓的重载,就是在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。相应的,重载的特点为:与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
重载示例:
//返回两个整数的和
int add(int x,int y){return x+y;}
//返回三个整数的和
int add(int x,int y,int z){return x+y+z;}
//返回两个小数的和
double add(double x,double y){return x+y;}

方法重写
方法重写指的是在子类中可以根据需要对从父类中继承来的方法进行改造,也称为方法的重置、覆盖。在程序执行时,子类的方法将覆盖父类的方法。方法重写的具体要求如下:

  ① 子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
  ② 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
 	     特殊情况:子类不能重写父类中声明为private权限的方法
  ③ 返回值类型:
 	* 父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
 	*父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
 	*父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)
  ④ 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型

注意:
子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写,要么都声明为static的(不是重写)。
重载和重写的区别?

  • 两者的概念不同。重载指的是一个类中同名不同参数列表方法间的关系,而重写指的是子类继承父类中的方法,并对父类中的方法进行覆盖。重写和重载是两码事。
  • 重载和重写的对方法的要求不同。重载只要求函数名相同,函数参数列表不同即可构成重载,对于重载方法间的修饰符、返回值类型等没有要求,而重写对方法的修饰符、放回值类型有具体的要求。
  • 重载不表现多态性,重写表现为多态性。重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;而对于多态,只等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。

可变个数的形参
JDK5.0新增,可变形参的使用有如下的注意点:

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

public void f(int a, String … names);

值传递
方法中的参数分为实参和形参,两者的概念如下:
形参:方法声明时的参数
实参:方法调用时实际传给形参的参数值
Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响,具体的参数传递规则如下:

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

栗子
基本数据类型:

    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        swap(a, b);
        System.out.println("a = " + a);//a = 10
        System.out.println("b = " + b);// b = 20
    }

    public static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    }

内存解析示意图
在这里插入图片描述
引用数类型

    public static void main(String[] args) {
        A a = new A();
        a.a = 30;
        A b = new A();
        b.a = 20;
        swap(a, b);
        System.out.println("a = " + a.a);
        System.out.println("b = " + b.a);

    }

    static class A {
        int a = 10;
    }

    public static void swap(A a, A b) {
        int temp = a.a;
        a.a = b.a;
        b.a = temp;
    }

内存解析
在这里插入图片描述

3.3 构造器

语法格式

修饰符 类名 (参数列表) {
初始化语句;
}

构造器作用:

创建对象;
给对象进行初始化

特征:

  • 它具有与类相同的名称
  • 它不声明返回值类型。(与声明为void不同)
  • 不能被static、final、synchronized、abstract、native修饰,不能有return语句返回值
    使用构造器的注意点
  1. Java语言中,每个类都至少有一个构造器
  2. 默认构造器的修饰符与所属类的修饰符一致
  3. 一旦显式定义了构造器,则系统不再提供默认构造器
  4. 一个类可以创建多个重载的构造器
  5. 父类的构造器不可被子类继承

属性赋值过程总结:
我们可以在很多个地方对属性进行赋值,包括:
① 默认初始化
② 显式初始化/代码块初始化
③ 构造器中初始化
④ 通过“对象.属性“或“对象.方法”的方式赋值
赋值的先后顺序为:
① -> ② -> ③ -> ④

3.4 代码块

在定义类时,通过花括号的方式内嵌于类中的代码称为代码块,代码块用来初始化类、对象的信息,可以使用static关键字修饰,有static关键字修饰称为静态代码块,无static关键字修饰成为非静态代码块。
静态代码块:用static 修饰的代码块

  1. 可以有输出语句。
  2. 可以对类的属性、类的声明进行初始化操作。
  3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
  4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
  5. 静态代码块的执行要先于非静态代码块。
  6. 静态代码块随着类的加载而加载,且只执行一次。

非静态代码块:没有static修饰的代码块

  1. 可以有输出语句。
  2. 可以对类的属性、类的声明进行初始化操作。
  3. 除了调用非静态的结构外,还可以调用静态的变量或方法。
  4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
  5. 每次创建对象的时候,都会执行一次。且先于构造器执行。

4. 抽象类和抽象方法

用abstract关键字来修饰一个类,这个类叫做抽象类;用abstract来修饰一个方法,该方法叫做抽象方法,含有抽象方法的类必须被声明为抽象类。
说明:
abstract修饰的类:抽象类

  • 此类不能实例化
  • 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
  • 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作 —>抽象的使用前提:继承性。

abstract修饰的方法:抽象方法

  • 抽象方法只方法的声明,没方法体
  • 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
  • 若子类重写了父类中的所的抽象方法后,此子类方可实例化若子类没重写父类中的所的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰。

注意点

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

栗子:
在航运公司系统中,Vehicle类需要定义两个方法分别计算运输工具的燃料效率和行驶距离。问题:卡车(Truck)和驳船(RiverBarge)的燃料效率和行驶距离的计算方法完全不同。Vehicle类不能提供计算方法,但子类可以。

public abstract class Vehicle{
public abstract double calcFuelEfficiency(); //计算燃料效率的抽象方法
public abstract double calcTripDistance(); //计算行驶距离的抽象方法
}
public class Truck extends Vehicle{
public double calcFuelEfficiency( ) { //写出计算卡车的燃料效率的具体方法 }
public double calcTripDistance( ) { //写出计算卡车行驶距离的具体方法 }
}
public class RiverBarge extends Vehicle{
public double calcFuelEfficiency( ) { //写出计算驳船的燃料效率的具体方法 }
public double calcTripDistance( ) { //写出计算驳船行驶距离的具体方法}
}

5. 接口

接口(interface)是抽象方法和常量值定义的集合,通过interface来定义。JDK7及以前,只能定义全局常量和抽象方法,JDK8后除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法。
接口使用说明:

  1. 接口中的所有成员变量都默认是由public static final修饰的;接口中的所有抽象方法都默认是由public abstract修饰的。
  2. 接口中没有构造器。
  3. 接口采用多继承机制。
  4. 定义Java类的语法格式:先写extends,后写implements

class SubClass extends SuperClass implements InterfaceA{ }

  1. 一个类可以实现多个接口,接口也可以继承其它接口。
  2. 实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。
  3. 接口的主要用途就是被实现类实现。(面向接口编程)
  4. 与继承关系类似,接口与实现类之间存在多态性

接口与抽象类的区别
在这里插入图片描述
java8中关于接口的新规

  1. 接口中定义的静态方法,只能通过接口来调用。
  2. 通过实现类的对象,可以调用接口中的默认方法。
    如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法。
  3. 如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,那么子类在没重写此方法的情况下,默认调用的是父类中的同名同参数的方法。–>类优先原则
  4. 如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没重写此方法的情况下,报错。–>接口冲突。这就需要我们必须在实现类中重写此方法
  5. 如何在子类(或实现类)的方法中调用父类、接口中被重写的方法
    public void myMethod(){
    method3();//调用自己定义的重写的方法
    super.method3();//调用的是父类中声明的
    //调用接口中的默认方法
    CompareA.super.method3();
    CompareB.super.method3();
    }

6. 内部类

在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。内部类一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称。内部类具有如下的分类:
成员内部类(静态、非静态 )
局部内部类(方法内、代码块内、构造器内)
成员内部类的理解

  • 成员内部类作为类的成员的角色:

和外部类不同,Inner class还可以声明为private或protected;
可以调用外部类的结构;
内部类 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;

  • 成员内部类作为类的角色:

可以在内部定义属性、方法、构造器等结构;
可以声明为abstract类 ,因此可以被其它的内部类继承;
可以声明为final的;
编译以后生成OuterClass$InnerClass.class字节码文件(也适用于局部内部类)。

注意点:

  1. 非static的成员内部类中的成员不能声明为static的,只有在外部类或static的成员
    内部类中才可声明static成员。
  2. 外部类访问成员内部类的成员,需要“内部类.成员”或“内部类对象.成员”的方式
  3. 成员内部类可以直接使用外部类的所有成员,包括私有的数据
  4. 当想要在外部类的静态成员部分使用内部类时,可以考虑内部类声明为静态的

局部内部类的使用

  • 只能在声明它的方法或代码块中使用,而且是先声明后使用。除此之外的任何地方都不能使用该类。
  • 但是它的对象可以通过外部方法的返回值返回使用,返回值类型只能是局部内部类的父类或父接口类型。
  • 局部内部类可以使用外部方法的局部变量,但是必须是final的。由局部内部类和局部变量的声明周期不同所致。
  • 局部内部类和局部变量地位类似,不能使用public,protected,缺省,private
  • 局部内部类不能使用static修饰,因此也不能包含静态成员

匿名内部类
使用格式

new 父类构造器(实参列表)|实现接口(){
//匿名内部类的类体部分
}

名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
匿名内部类的特点如下:

  1. 匿名内部类必须继承父类或实现接口
  2. 匿名内部类只能有一个对象
  3. 匿名内部类对象只能使用多态形式引用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值