Advertisement

面向对象编程基础

阅读量:

面向对象编程基础

1.1面向对象概述

复制代码
复制代码
复制代码
复制代码
复制代码

1.2 对象

对象可被定义为一种抽象的概念...其英文名称通常缩写为"Object"。它代表所有存在的事物,在现实世界中能够被肉眼看见的事物都属于这一类别。在现实世界中能够被肉眼看见的事物都属于这一类别;直观地理解这些实例有助于更好地掌握这一概念。例如:人、手机、电脑;直观地理解这些实例有助于更好地掌握这一概念;直观地理解这些实例有助于更好地掌握这一概念。

1.2.1 对象的组成

将一个实例划分为两部分:一部分用于描述其外观与功能特性;另一部分则定义其执行的行为与操作步骤。在编程语言中,默认将用于描述实例外观的部分称为属性;而将其定义为执行操作的行为则通常采用"行为"或"方法"来表示;这些术语共同构成了对实例功能的完整定义。例如:比如性别作为该实例的一个属性;个体如人不仅具备行走的能力还能进行进食及学习行为等基本操作。

实体(对象)由属性和行为组成,也就是实体(对象)的外观和功能。

1.3 类

该结构充当了封装对象属性与行为的承担者;也即所有具备相同属性与行为的一组实体均可称为一类(相对直观的理解即是分类)。举例而言像大雁群体这样的集合就可以被看作是一个"飞行动物"类别——因为它们都具备相似的嘴型翼展以及爪形特征;同时它们也都具备相似的行为模式包括飞行觅食以及休息等日常活动。因此这种分类方式在程序层面则意味着这个群体自然构成一个"飞行动物"实例。

从这两张流程图中可以看出,在大雁群中所有的大雁都具有统一的外观特征和行为模式(功能),因此,在这种分类体系下,我们可以将这类生物统称为该分类中的成员或实例。

总结: 类可以理解为分类,是抽象的。而对象就是实体可以看得到模得着的。

1.3.1 OOP程序设计特点简单介绍

面向对象程序设计具有以下三个通用特点:

  • 封装性

  • 继承性

  • 多态性

a).封装

封装是主要对象编程的概念。其将对象的特征与功能封装在一起作为工具使用。这些工具通常会隐藏实现内容的具体细节。这也就形成了封装的思想。换句话说,在现实生活中面对物品或商品时,只要满足你的使用需求即可;至于其内部如何运作则无需过多关注。例如:当我们使用手机进行通话时(计通话),我们只需关心是否能成功连接即可(通断),至于通讯线路的具体技术实现则无需深入探究。

总结: 封装的思想被程序采用的主要目的是确保类内数据结构的完整性和安全性。此类用户的访问只能限于对允许公开的数据进行操作。从而防止外部干预导致的数据变更。封装不仅提高了程序的安全性还增强了其可维护性。

b).继承

作为所有程序设计语言中不可或缺的一项机制,继承扮演着将新概念融入现有体系的重要角色。它使得新创建的类型能够在现有结构上进行扩展,并复用其已有的功能与属性。这种机制不仅简化了代码编写过程,还增强了系统的可维护性。通过定义新的子代类型与基元类型之间的关系(其中新创建的类型被称为子代类型 ,而原有的类型则称为基元类型),我们能够有效地组织代码结构并促进信息共享。值得注意的是,在Java编程语言中,默认采用单一继承模式,在这种情况下每个子代类型只能有一个基元类型作为其来源。因此,在设计过程中必须明确各层基元类型的选取与分配方式以避免潜在的技术限制

c).多态

实现父类对象在子类中的应用即为多态。直观上来说, 多态意味着多种形态, 但在此情况下, 每一个实例(对象)仍然保留了父类的所有特征和行为。

2.类与对象

在上面我们认识类的时候已经介绍过,在学习过程中我们已经了解到,类是我们将实体(对象)的外观特征(属性)和行为作为承载者进行包装的过程。也就是说这类实体(对象)所具有的各种外观特征和功能都可以通过类来进行包装描述。

2.1 类的声名

语法:

复制代码
    public class 类名称 {
复制代码
     //类的主体....
复制代码

注意:

  1. 当一个Java源代码文件内仅包含单一的一个class定义时,则该源代码 file name 必须与其 class name完全吻合;
  2. 每个单独的 Java source file 文件实体最多只能声明一个 single public class 类;
  3. 当某 Java source file 文件实体内定义了超过一个 class 定义时,则该 file name 必须与其 public class name完全吻合;
  4. 若某 Java source file 文件实体内定义了多个 class 定义且未声明任何 public class 时,则该 file name 可选择性地与其任何一个 class name保持一致;

Java类名的命名规则:

  1. 类名必须采用下划线_或字母作为起始字符,并建议以字母开头;
  2. 名称中的首字母通常建议大写化;
  3. 若类名包含多个单词,则每个单词的首字母应尽量大写;
  4. 类名不得使用Java保留字如String、this等。
2.2 成员变量

在Java中实体(对象)具有属性也被称为成员变量;其命名规则与普通变量相同。

复制代码
    数据类型 变量名称 [ = 值 ];

提示: 在代码中使用[ = 值]时,默认情况下该参数留空或不设置;若需要,则需在其前后明确赋予特定值。

让我们举个例子来说明这一点:比如将鸟类抽象为Bird类代表了鸟这一概念。在这个过程中,Bird类中的成员变量对应于对象属性即生物体的各种特征。具体来说这些特征包括翅膀、爪子等身体结构以及它们所扮演的功能如飞行的能力等这些都是构成鸟的关键组成部分因此在Bird类中应设置四个成员变量:wing(翅膀)、claw(爪子)、beak(嘴巴)、feather(羽毛)。

复制代码
    //定义一个Bird鸟类
复制代码
    public class Bird {
复制代码
     String wing;     //翅膀
复制代码
    String claw;      //爪子
复制代码
    String beak;      //嘴巴
复制代码
    String feather;     //羽毛
复制代码

从分析可知,在代码中使用关键字class来定义一个名为Bird的新类。该新类在其名称下设置了四个成员变量,并且这些成员变量的数据类型必须是合法的Java数据类型。此外,在该新类内部声明了四个成员变量,并且这些成员变量的作用与普通变量并无区别。这些成员变量既可以被初始化为某个特定的初值,默认情况下也会被赋予一个默认值。

数据类型 默认值 详细说明
float、double 0.0 浮点零
char '' 空格字符
boolean false 逻辑符
引用类型,如:String null 空值
int、byte、short、long 0 0值

上面是我们在定义类时使用的一些数据类型以及对应的默认值。

2.2 成员方法
2.2.1 成员方法的定义

成员方法与类对象(实体)之间存在关联关系,其主要功能是用来定义类中的可执行操作;操作或属性则由一系列语句构成的代码块来实现。

语法:

复制代码
    权限修饰符] [返回值类型] 方法名 ([参数类型 参数名]){
复制代码
    //方法体 -> 一系列代码
复制代码
    return 返回值;
复制代码

分析:

  1. 访问权限修饰符可取private、public、protected中的任意一种形式,并非强制使用。其主要作用在于限定操作者对特定对象或资源的操作权限,在后续章节中将详细阐述这一机制。
  2. 返回数据类型的定义旨在明确操作完成后的输出内容。这些数据类型的种类繁多,包括基本数据如整数和字符串以及更为复杂的对象结构。若操作无需输出结果,则采用void关键字以表明结果不存在。
  3. 方法体的设计灵活性较高允许既包含输入参数也支持无参形式同时所接受的对象不仅可以是类别的实例还涵盖了基础数据类型的适用性。
复制代码
    class Person {
复制代码
     String name = "张三"; //成员变量也称之为类对象属性
复制代码
复制代码
    //定义一个方法作用是做一个自我介绍
复制代码
    //不需要数据返回
复制代码
    public void showInfo(){
复制代码
      System.out.println(name);
复制代码
复制代码
复制代码
    //java文件名为Per.java
复制代码
    public class Per {
复制代码
      public static void main(String[] args){
复制代码
     Person p = new Person();
复制代码
    p.showInfo(); //输出:张三
复制代码
复制代码

注意:

函数必须声明在一个具体的类体中;当未指定权限修饰符时,默认情况下该函数仅限于当前类别及其所属包中的其他类型进行访问。

当所定义的方法设置了返回值时,在该方法内必须使用return关键字并显示出来指定类型的数据显示出来,并且所返回的数据类型应当与该方法设定的返回数据类型保持一致。

复制代码
    public class Per{
复制代码
      public static void main(String[] args){
复制代码
复制代码
复制代码
    public int showInfo(){
复制代码
     System.out.println("Hi,Java");
复制代码
    return 1;
复制代码
复制代码
2.2.3 成员方法的参数

当调用某个特定的方法时可以将其所需的各种数据通过传递的方式送到该方法中进行处理;这些被传递的数据被称为(输入)参数;这些参数会被目标方法接收并存储起来以便后续的操作;需要注意的是,在程序设计过程中为了避免混淆通常会将接受输入数据的部分命名为输入端口而将实际存储数据的部分命名为输入框以区分它们各自的功能特点;此外需要注意的是,在编程语言设计中为了实现某种特定功能有时需要引入新的结构或机制因此对现有功能进行优化可能会遇到一些限制;

  1. 值参数
  2. 引用参数
  3. 不定长参数

【值参数:】

在传递机制上采用'按值传递'的方式,在调用该数值型函数时,在编译阶段会预先分配足够的存储空间用于接收形式参数的数值,并在此之后将实际参与者的当前数值逐一赋入对应形式参数中。因为采用的是'按值传递'策略,在函数内部对形式参数进行修改不会影响实际参与者的数值。

放置于书架上的书籍共计30本储存在箱中的书籍共有40册将所有位于书架上的书籍转移至箱子中后请调用包含参数的方法计算箱子内书籍总量

复制代码
    public class Book{
复制代码
      public static void main(String[] args){
复制代码
      Book b = new Book();
复制代码
      int num1 = 30;
复制代码
    int num2 = 40;
复制代码
    int box = b.add(num1, num2);
复制代码
复制代码
    //打印箱子中书本总数
复制代码
    System.out.println("箱子书总数为:" + box);
复制代码
复制代码
复制代码
    //统计箱子中所有书本
复制代码
    public int add(int num1, int num2){
复制代码
    int box = 0;
复制代码
    box = num1 + num2;
复制代码
    return box;
复制代码
复制代码

【引用参数:】

当向一个方法传递其数据类型的组织时(例如一个数组或引用对象),如果这些数据结构中的某些元素被修改或重置,则这些修改会被原有结构继承并反映出来。我们称此类别为'引用型'数据结构。

现将1, 10, 100美元用于存储于double数组中,并通过引用参数实现其中的美元转换为人民币。
例如:
6.903

复制代码
    public class Rate{
复制代码
      public static void main(String[] args){
复制代码
      double[] arr = {1, 10, 100};
复制代码
复制代码
    //输出数组中的美钞
复制代码
    for(int i = 0; i < arr.length; i++){
复制代码
      System.out.println(arr[i] + "美元");
复制代码
复制代码
复制代码
    //调用方法change
复制代码
    change(arr);
复制代码
复制代码
    //再次输出数组中数据
复制代码
    for(int i = 0; i < arr.length; i++){
复制代码
    System.out.println(arr[i] + "元");
复制代码
复制代码
复制代码
复制代码
    //定义一个方法,参数为一维数组(形参)
复制代码
    public void change(double[] arr){
复制代码
      for(int i = 0; i < arr.length; i++){
复制代码
    arr[i] *= 6.903; //换算成RMB
复制代码
复制代码
复制代码

【不定长参数:】

在声明一个成员函数时(即当声明一个成员函数时),若该函数接受多个同类型参数,则该函数可支持不定长参数的实现

复制代码
    public class Scal{
复制代码
      public static void main(String[] args){
复制代码
    int num1=20,num2=42,num3=32,num4=329,num5=329;
复制代码
    Scal s = new Scal();
复制代码
    int sum1 = s.add(num1, num2); //只计算二个数值的和
复制代码
    int sum2 = s.adds(num1,num2,num3,num4,num5);
复制代码
复制代码
    System.out.println("sum1=" + sum1);
复制代码
    System.out.println("sum2=" + sum2);
复制代码
复制代码
复制代码
    //计算二个数之和
复制代码
    public int add(int num1, int num2){
复制代码
    return num1 + num2;
复制代码
复制代码
复制代码
    //计算一系列整数之和
复制代码
    public int adds(int... num){
复制代码
    int sum = 0;
复制代码
    for(int i = 0; i < x.length; i++){
复制代码
    sum += x[i];
复制代码
复制代码
    //返回和
复制代码
    return sum;
复制代码
复制代码
2.3 局部变量

局部变量从字面意思来理解就是在一定范围内有效。

定义: 成员方法内部定义的变量,那么这个变量就是局部变量。

分析:在方法运行期间,局部变量会被动态生成;一旦方法完成执行,这些变量就会被释放。需要注意的是,在访问局部变量之前必须进行赋值或初始化操作;否则会导致编译错误。

复制代码
    public class Demo{
复制代码
    public static void main(String[] args){
复制代码
      Demo d = new Demo();
复制代码
    d.sayHello();
复制代码
复制代码
复制代码
    //说hello
复制代码
    public void sayHello(){
复制代码
      String name = "Java"; //是在方法sayHello体内声明的所以是局部变量
复制代码
    System.out.println(name);
复制代码
复制代码
复制代码
2.4 构造方法
2.4.1无参构造方法定义

在类中除了成员函数外还存在一种特殊的函数类型,这种函数通常被称为构造函数。它具有与当前类名称相同的名称,在对象实体的初始化过程中会被调用以完成对象创建的过程。换言之,在每次实例化一个对象时该类都会自动调用这个函数进行初始化

构造方法的特点:

  • 构造方法没有返回类型,也不能定义void

  • 构造方法的名称要与本类的名称相同

  • 构造方法的主要功能是执行初始化操作;也可以将用于定义对象的参数传递给对象成员。

分析:

当定义类的一个成员函数时,该成员函数无返回类型(必须牢记)。同时也要知道普通无返回类型的成员函数与构造函数不同,在定义普通无返回类型的成员函数时采用public void methodName()的形式进行定义;而构造方法并不需要附加void关键字。

复制代码
    public class 类名 {
复制代码
      //构造方法
复制代码
    public 类名() {
复制代码
复制代码
复制代码

注意:

  1. public修饰符关键字不能少
  2. 类名一定要保持一致
2.4.2 定义有参构造方法

在使用构建函数的情况下,我们可以将数值分配给字段。这使得在实例化本类别的一个对象时,在这种情况下字段也会得到初始化。如果没有显式地定义构建函数,则编译器会在这种情况下自动生成一个无参数且默认执行构建操作的功能函数。

复制代码
    public class Book {
复制代码
    //书名
复制代码
    String name;
复制代码
    //定义一个有参数的构造方法
复制代码
      public Book(String str){
复制代码
    name = str;
复制代码
复制代码

注意:

  1. public修饰符关键字必须包含
  2. 类名必须统一
  3. 构造方法的支持范围可选性强

分析:

如果在一个类中定义了带有参数的构造函数(constructor),那么编译器就不会自动生成一个默认无参数的构造函数。因此需要记住的是,在无法通过显式定义为类带来默认无参数 constructors 的情况下(即当类中没有定义任何 constructors 时),编译器才会主动生成这样的默认函数。

复制代码
    public class Per{
复制代码
      public static void main(String[] args){
复制代码
    Per p = new Per();
复制代码
    p.sayHello("张三", "男");
复制代码
复制代码
    //无参构造方法
复制代码
    public Per(){
复制代码
复制代码
    //介绍自己
复制代码
    public void sayHello(String name, String sex){
复制代码
      System.out.println("我的名字"+ name + ",性别是" + sex);
复制代码
复制代码
复制代码
    public class Per{
复制代码
    String username; //成员变量
复制代码
    String agender;  //成员变量
复制代码
      public static void main(String[] args){
复制代码
复制代码
复制代码
    //有参构造方法
复制代码
    public Per(String name, String sex){
复制代码
      username = name;
复制代码
    agender = sex;
复制代码
复制代码
    public void sayHello(){
复制代码
    System.out.println("我的名字是:" + username + ",性别为:" + agender);
复制代码
复制代码
2.5 this关键字

该关键字在方法体内标识当前类的实例。类作为载体能够生成多种不同的对象。当创建的对象调用方法时,在被调用的方法体内存在This关键字,则该关键字代表的是当前对象自身。

关于this的三种用法:

1.区分成员变量和局部变量

复制代码
    public class Demo{
复制代码
      public static void main(String[] args){
复制代码
       Demo2 d = new Demo2("张三", 32);
复制代码
    d.sayHello();
复制代码
复制代码
复制代码
复制代码
    class Demo2{
复制代码
    String name; //名字
复制代码
    int age; //年龄
复制代码
      public Demo2(String name, int age){
复制代码
    name = name;
复制代码
    age = age;
复制代码
复制代码
复制代码
    //说出自己个人信息
复制代码
    public void sayHello(){
复制代码
    System.out.println("我的名字是" + name + ",年龄为" + age);
复制代码
复制代码

输出结果为:我的名字是null,年龄为0

如果我们在构造方法中没有使用this来进行标识区分,则会发现当执行name = name和age = age时实际上是处理的是两个不同的局部变量操作。即当执行localVariableName = localVariableName时实际上并没有对成员变量产生任何修改作用。因此成员变量name从未被修改过。

复制代码
    public class Demo{
复制代码
      public static void main(String[] args){
复制代码
       Demo2 d = new Demo2("张三", 32);
复制代码
    d.sayHello();
复制代码
复制代码
复制代码
复制代码
    class Demo2{
复制代码
    String name; //名字
复制代码
    int age; //年龄
复制代码
      public Demo2(String name, int age){
复制代码
    this.name = name;
复制代码
    this.age = age;
复制代码
复制代码
复制代码
    //说出自己个人信息
复制代码
    public void sayHello(){
复制代码
    System.out.println("我的名字是" + name + ",年龄为" + age);
复制代码
复制代码

输出结果为:我的名字是张三,年龄为32

在构造方法中, 当参数名称与成员变量相同时, 则可以通过 this来进行区分.

2.构造方法中的使用

复制代码
    public class People{
复制代码
      String name; //姓名
复制代码
      int age; //年龄
复制代码
      String agender; //性别
复制代码
复制代码
      public static void main(String[] args){
复制代码
    People p = new People("张三");
复制代码
    p.sayHello();
复制代码
      }
复制代码
复制代码
      public People(String name, String agender, int age){
复制代码
    this.name = name;
复制代码
    this.agender = agender;
复制代码
    this.age = age;
复制代码
    System.out.println("这是类的第一个构造方法");
复制代码
      }
复制代码
复制代码
      public People(String name, String agender){
复制代码
    this.name = name;
复制代码
    this.agender = agender;
复制代码
    System.out.println("这是类的第二个构造方法");
复制代码
      }
复制代码
复制代码
      public People(String name){
复制代码
    this.name = name;
复制代码
    System.out.println("这是类的第三个构造方法");
复制代码
      }
复制代码
复制代码
      public void sayHello(){
复制代码
    System.out.println("name=" + name + ",agender=" + agender + ",age=" +age);
复制代码
      }
复制代码

输出的结果为: 这是类的第三个构造方法 name=张三,agender=null,age=0

如果在类构造方法中使用this关键字后

复制代码
    public class People{
复制代码
      String name; //姓名
复制代码
      int age; //年龄
复制代码
      String agender; //性别
复制代码
复制代码
      public static void main(String[] args){
复制代码
    People p = new People("张三");
复制代码
    p.sayHello();
复制代码
      }
复制代码
复制代码
      public People(String name, String agender, int age){
复制代码
    this.name = name;
复制代码
    this.agender = agender;
复制代码
    this.age = age;
复制代码
    System.out.println("这是类的第一个构造方法");
复制代码
      }
复制代码
复制代码
      public People(String name, String agender){
复制代码
    this(name, agender, 32);
复制代码
    this.name = name;
复制代码
    this.agender = agender;
复制代码
    System.out.println("这是类的第二个构造方法");
复制代码
      }
复制代码
复制代码
      public People(String name){
复制代码
    this(name, "男");
复制代码
    this.name = name;
复制代码
    System.out.println("这是类的第三个构造方法");
复制代码
      }
复制代码
复制代码
      public void sayHello(){
复制代码
    System.out.println("name=" + name + ",agender=" + agender + ",age=" +age);
复制代码
      }
复制代码

输出结果为:

这是类的第一个构造方法 这是类的第二个构造方法 这是类的第三个构造方法 name=张三,agender=男,age=32

3.表示当前对象

复制代码
    public class Demo{
复制代码
    String name;
复制代码
    int age;
复制代码
      public static void main(String[] args){
复制代码
    Demo d = new Demo("张三", 32);
复制代码
    System.out.println(d.name + d.age);
复制代码
复制代码
复制代码
    public Demo(String name, int age){
复制代码
      this.name = name;
复制代码
    this.age = age;
复制代码
复制代码

分析:

在构造方法中设置this.name等于将d的属性name赋值为'张三'

3 static关键字

在代码中使用static关键字对变量、方法和常量进行修饰后,则这些变量、方法和常量被称为静态变量或静态成员;同样地也可以将它们视为类的静态成员。

类名.静态成员

类名.静态成员

类名.静态成员

3.1 静态变量
复制代码
    public class StaticStu
复制代码
复制代码
      public static String name = "";
复制代码
复制代码
      public static void main(String[] args){
复制代码
    name = "张三"; //等价于StaticStu.name = "张三"
复制代码
    System.out.println(name);
复制代码
      }
复制代码
复制代码
复制代码
    //输出的结果为:张三

注意:

在类中使用静态成员可以直接使用,也是不需要实例化。

3.2 静态方法
复制代码
    public class StaticStu
复制代码
复制代码
      public static void main(String[] args){
复制代码
    StaticStu.SayHello();
复制代码
      }
复制代码
复制代码
    public static void SayHello(){
复制代码
      System.out.println("深夜了");
复制代码
复制代码
复制代码
    //输出结果为:深夜了

注意:

在编程中,在变量的定义及其应用与之相似,在这种情况下都会采用static进行修饰。此外,在这种情况下无需实例化即可直接调用相关属性或方法。

3.3 静态代码块

具有成员的类也就是拥有自己的行为。这些行为即为该类的一个静态部分。其主要功能与构造方法相同是为了为该类进行初始化工作。

复制代码
    public class StaticStu
复制代码
复制代码
    static {
复制代码
    System.out.println("我是类的代码块,我初始化了");
复制代码
复制代码
      public static void main(String[] args){
复制代码
      }
复制代码
复制代码
复制代码
    //输出结果为:我是类的代码块,我初始化了

注意:

类有代码块那么对象也有代码块,直接是以{}即可。

全部评论 (0)

还没有任何评论哟~