华清远见重庆中心—面向对象技术总结/个人总结

本文主要总结了面向对象技术,包括方法的定义与调用、面向过程与面向对象编程思想的对比、类与对象的概念及关系、构造方法、继承、封装、多态等核心概念。通过实例讲解了类的定义、对象的创建、方法的调用方式、以及面向对象编程中的抽象、接口和静态成员的使用。此外,还提到了一些重要的关键字如`this`、`super`、`final`和`abstract`,以及接口和枚举的应用。最后,作者分享了个人在学习面向对象技术过程中的心得和一个小项目的实践应用。
摘要由CSDN通过智能技术生成

方法

方法是定义在类中的一段独立代码,能完成某个事情。

定义方法时,提供方法的名称、返回值类型、参数列表,这三点称为方法三要素,定义的方法都需要这三部分。

当再使用该方法中的代码时,只需通过该方法名称调用即可。

方法能够减少代码冗余。

调用方法

  1. 通过类名调用

Math类

Math类时Java中的工具类,用于数学计数。

该类中的方法和属性都使用static修饰的,可以直接通过类名调用。

在任何类中,通过快捷键alt+7,展示方法列表。

//常用方法属性
System.out.println(Math.PI);// 圆周率
System.out.printlin(Math.E);// 自然常数
System.out.println(Math.abs(-5));// 绝对值
System.out.println(Math.max(1,2));// 最大值
System.out.println(Math.min(2,3));// 最小值
System.out.println(Math.ceil(2.1));// 3 向上取整
System.out.println(Math.floor(3.9));// 3 向下取整
System.out.println(Math.round(-1.5));// -1 四舍五入
System.out.println(Math.random());// [0,1] 直接的随机数
System.out.println(Math.sqrt(9));// 3 平方根
Systrm.out.println(Math.cbrt(27)); // 3 立方根
System.out.println(Math.pow(2,3));// 2的3次幂
  1. 通过对象调用

创建对象:类名 对象名 = new 类名([参数]);

Scanner sc = new Scanner(System.in)
sc.方法名();

Random rd = new Random();
rd.方法名();

3.在同一个类中,方法A直接调用方法B

class Test{

    void funA(){
          funB;
    }

     void funB(){
       System.out.println("我是B方法");
      }
}

方法的调用

调用方式

  • 通过类名调用

  • 通过对象调用

  • 直接调用

参数

  • 无参数

Scanner sc = new Scannner(System.in);
sc.next();// 调用无参数方法
  • 有参数

Random rd = new Random();
rd.nextInt(); // 调用有参数方法

返回值

  • 没有返回值,方法名的前面用void表示

calss Test{
    void funB(){
     System.out.println("我是B方法");
     }
    public static void maia (String[] args){
        Test t = new Test();
        t.funB();
     }
}
  • 有返回值

Random rd = new Random();
int num = rd.nextInt(10);

自定义方法

方法的三要素

  • 方法名

  1. 使用驼峰命名法

  • 方法返回值类型

  1. 如果有返回值,使用Java中的任意数据类型,方法体中使用return关键字返回对应类型的数据

  1. 如果没有返回值,使用void关键字

  • 方法参数

  1. 参数写法:数据类型 形参名,数据类型 形参名

[修饰符] 返回之后类型 方法名(参数列表){
   方法体;
}

方法的类型

无参数无返回值

void 方法名(){
    // 方法体
         return; // 遇到return立即结束方法
}

无参数有返回值

int 方法名(){
          return new Random().nextInt();
}

有参数无返回值

void 方法名(数据类型 形参名,数据类型 形参名){
       // 方法体
         return;
} 

有参数有返回之后

// 生成a,b中包含最小值,不包含最大值范围内的随机数
double rand (int a ,int b){
        double num = Math.floor(Math.random()*Math.abs(a-b)+Math.min(a,b));
        return num;
}

注意

  • 有返回值的方法,必须要在方法体中加入return并能够执行,同时要return一个该方法返回值类型对应的数据

  • 没有返回值的方法,可以不加return关键字。如果加入return关键字,不能跟上数据

  • 方法中出现return,会立即结束方法,所以return语句之后不能再有代码

  • 定义方法时的参数称为形式参数,简称形参,调用方法时,实际传递的参数称为实际参数,简称实参,实参只需要保证数据类型和形参相同即可。

编程思想

面向过程编程

Procedure Oriented Programming 简称POP

是一种基本的编程思想,将一件事情按流程按步骤执行,逻辑清晰。

每一步都是基于上一步的流程去继续实现。

注重于分析问题的步骤

如果逻辑复杂,如xxx管理系统,使用POP就会变得很玛法

C语言就是一门面向过程的编程语言

面向对象编程

Object Oriented Programming 简称OOP

是一种编程思想,核心是创建解决问题的对象,赋予对象行为和特征,让这些对象互相配合执行。

每个对象的行为实际也是面向过程

注重于全局如何创建完成某件事情的对象,如果适时的调用

这种思想致力于将计算机中的世界,描述的和现实中一致的思想

如洗衣服

pop:得到衣服-得到洗衣服-洗-晾晒

oop:得到衣服对象、得到洗衣机对象、调用洗衣机对象的洗衣服行为

总结

  • 面向过程:亲力亲为,侧重于分析完成事情的过程

  • 面向对象:所有事情交给相应的对象完成,侧重于如何创建解决问题的对象

类和对象

类Class

具有相同属性和行为的对象的集合。相当于模板。

  • 属性

  1. 描述这个类的特征值,在程序中,通过定义变量实现

  • 行为

  1. 描述这个类的动作,在程序中,通过定义方法实现’

  1. 创建一个class文件,就是创建一个类

定义类

[修饰符] class类名 {

// 属性(定义变量)
// 行为(定义方法)
}
/*
*定义车的模板
*属性:变量
*品牌
*颜色
*座位数
*排量
*
*行为:方法
*跑
*说话
*飞
*/
public class car{
        //定义变量 数据类型 变量名;
        String brand;
         String color;
         int seat;

          // 定义方法
      void run(){
        System.out.println("车在跑。。。");
        }
     void introduce(){
          // 在方法中可以直接访问同一个类中的属性
          System.out,println("我是一辆车"+brand+"牌的"+color+"色的"+seat+"座车");
  }
}

对象Object

对象由某个类创建出来的具体实例

创建对象

类名 对象名 = new 构造方法([参数]);

创建出的对象,通过 "." 操作符访问类中的非私有属性和方法

public class Test{
    public static void main(String[] args) {
           // 创建Car类的对象
           // 类名 对象名 = new 类名();
                Car benz  = new Car();
            // 对象.类中的属性和方法
                 benz.seat = 5;
                 benz.color = "白";
                benz.brand = "奔驰";

                  benz.introduce();
                   benz.run();
     }
}

类和对象的关系

对象是类的具体表现,类是对象的模板。

如制作月饼的模具就是一个类,每次用这个模具创建出来的月饼就是一个对象。

先定义类,才能通过该类获取对象

成员变量和局部变量

成员变量

定义在类中的变量,称为成员变量,有默认值。

局部变量

定义在方法中的变量,称为局部变量。没有默认值,赋值后才能使用。

成员变量和局部变量相关面试题

简述成员变量和局部变量的区别以及生命周期

成员变量是定义在类中的变量,有默认值,不赋值也能使用

局部变量是定义在方法中的变量,没有默认值,需要赋值后才能使用

成员变量的生命周期:类创建对象,成员变量就会初始化;类的对象被回收,成员变量就会销

局部变量的生命周期:方法调用,对局部变量赋值,局部变量初始化,方法调用结束,局部变

量失效。

class Person{

String name;//成员变量,String是类类型,属于引用类型,默认为null

int age;//整型,默认0

double[] list;

void fun(){

System.out.println(name);//这里能通过编译,可以使用name,输出null

System.out.println(list[0]);//这里能通过编译,由于list为null,会报空指针异常

}

}

class Test{

public static void main(String[] args){

int num;//定义在方法中的变量称为局部变量,赋值后才能使用

System.out.println(num);//无法通过编译

}

构造方法

概念

构造方法也称为构造函数、构造器、constructor

它是一个特殊的方法。

没有返回值部分,方法名和类名一致,在创建对象时通过new调用,给类的成员变量赋值。

特点

创建对象时必须通过new配合构造方法

构造方法没有返回值部分,名称和类名相同

构造方法可以存在多个,但是参数不能相同。这些构造方法之间的关系称为方法重载

每个类默认有一个隐藏的无参数的构造方法,方法体中隐含了一句super()。用于创建无参数的对象

如果自己写了带参数的构造方法,默认无参数的构造方法就会失效。如果想要同时拥有带参数和不

带参数的构造方法,

就需要再次显式地写出来

带参数的构造方法常用于初始化成员变量(给类中的变量赋值)

构造方法可以限制创建对象时携带的参数

构造方法无法通过"."操作符访问,只能通过new关键字创建对象时调用

IDEA中自动生成构造方法

在类空白处右键generate或快捷键alt+insert

在弹出的窗口中,选择Constructor

选择生成的构造方法的参数,全选ctrl+a

面向对象语言的三大特性--封装

封装

使用private关键字对成员变量进行修饰。再提供一组get和set的方法,用于对该属性读取和赋值。

可以防止除自身类之外的地方对private修饰的属性进行访问。

这样就能保护关键属性或给属性赋一个合理的值。

步骤

1.创建类,编写成员变量,对成员变量使用private修饰

2.给所有成员变量添加set方法,用于赋值

3.给所有成员变量添加get方法,用于读取

IDEA中自动生成getter/setter方法

在类中空白处右键generate或快捷键alt + insert,在弹出的窗口中选择getter and setter

在弹出的窗口中,选择要生成get和set方法的成员变量

面向对象三大特性--继承

概念

类B使用extends(延伸)关键字"继承"类A。

语法:class 类B extends 类A{}

类B称为类A的子类,衍生类,subClass

类A称为类B的父类,超类、supClass

继承后,子类就能访问父类中的非私有(没有使用private修饰)成员变量和成员方法。

将多个类中的公共代码提取出来保存到一个公共类中,这些类使用extends"继承"这一个公共类,从而减

少这些类中的冗余代码。

如猫类、狗类都有类型、昵称等属性,也有吃、睡等方法,那就可以定义一个动物类,将这些公共的属

性和方法定义在动物类这个父类中,

再让猫类和狗类这些子类继承动物类。这样就能直接通过子类访问父类中的内容。

特点

如果多个类之中有相同的代码,可以将这些代码提取出来到一个公共的类中,这个类就是父类。再

让那些类去extends继承这个父类,那些类就是子类。子类就无需再写重复代码

子类中或子类对象可以直接访问父类中非私有(不用private修饰)属性和方法

创建子类对象时,会先执行父类中相应的构造方法

子类继承父类后,通常会对对父类中的方法进行拓展或覆盖,这称为方法重写。重写后,子类再调

用该方法时,执行的是重写后的内容

Java中是单继承。一个子类只能extends一个父类,一个父类可以有很多子类

Java中可以多重继承,类A可以继承类B,类B继承类C,这是类A既是类B的子类,也是类C的子

类,类A可以访问类B和类C中的非私有成员

任何类都是Object类的子类

方法重写和方法重载

方法重写override

当子类继承父类后,可以对父类中的方法进行扩展或覆盖。这个过程称为方法重写。

方法重写要求

方法名、返回值、参数列表必须和父类一致

访问权限不能比父类更严格(访问修饰符的范围要么一致要么更大)

不能抛出比父类更大的异常

IDEA中如果要重写方法,使用CTRL + O在弹出的窗口中选择要重写的方法

方法重载overload

在一个类中,如果多个方法的方法名相同,参数列表不同时,这些方法称为重载的方法。

同名不同参

重载用于,在一个类中,某个方法在不同的条件下,执行不同的内容。

方法重载要求

方法名相同

参数必须不同(数量、类型)

与返回值无关

重载和重写相关面试题

说出重载与重写的异同

相同点:方法名不变

不同点:

重载在一个类中,重写在继承关系中子类重写父类

重载参数必须不同,重写参数必须相同

重载返回值无要求,重写返回值必须相同

构造方法能重载吗?能重写吗?构造方法可以重载。构造方法不能重写。

构造方法在执行时,一定会创建对象吗?

不一定。创建子类时会自动执行父类构造方法,但不会创建父类对象。

以下代码执行会输出什么结果

this和super关键字

这两个关键字,都可以当做对象使用,也可当做构造方法使用。

当做对象使用

用法:this.属性或this.方法,super.属性或super.方法

此时的this表示当前类的对象,super表示当前类的父类对象

当做构造方法使用

用法:this([参数])或super([参数])

此时的this([参数])表示当前类的某个构造方法。如this()表示当前类的无参构造方法。

super([参数])表示当前类的父类的某个方法。如super()表示当前类的父类的无参构造方法。

如果当做构造方法使用时,只能写在另一个构造方法的第一行。

注意

如果父类中有无参数的构造方法,在子类的构造方法中,可以不写super(),默认自动调用。

如果父类中有带参数的构造方法,没有无参数的构造方法,在子类的构造方法中,必须要有super([参

数])。

父类和子类中都没有构造方法(只有默认的无参构造方法)

父类中没有无参构造方法,子类中就必须调用父类中对应的构造方法

包package

通过包可以将.java源文件进行结构化管理,相当于windows中的文件夹。

不同的包中,可以保存相同的.java源文件。

某个类在某个包中时,会在该类的代码最上加入 package 包名 ;

包的命名

包名通常使用公司域名的倒序形式。

baidu.com是百度的域名,有一个test的项目,包名写为com.baidu.test

包名中的".",相当于进入文件夹

如com.baidu.test,会创建3个文件夹:com下有baidu,baidu下有test。

导入包

如a包中的类要使用b包中的类时,需要在a包中的类中,导入b包或b包中的某个类。

如在使用Scanner时,就需要导入Scanner所在的java.util包。 import java.util.Scanner;

在IDEA中,如果是通过自动补全的形式写的代码,会自动导入该类,

或设置自动导包删包。

如果需要手动导入包,在报错的位置上按下快捷键alt+回车,

如果多个类,类名相同但在不同的包中,使用该类时选择合适的包。

访问修饰符

访问修饰符可以限制某个类、属性或方法的访问权限

用法:

修饰类:访问修饰符 class 类名{}

修饰属性:访问修饰符 数据类型 变量名;

修饰方法:访问修饰符 返回值类型 方法名(){}

访问权限表

访问权限从大到小

public >>> protected >>> 默认的 >>> private

final关键字

修饰属性

当final修饰属性时,该属性的值不可更改,这个属性称为常量。

常量在程序运行过程中,保存的值不能编号,所以定义常量时需要初始化。

常量名所有字母大写,多个单词之间用_隔开。

修饰方法

当final修饰方法时,该方法不能被重写。

在方法的返回值前加上final。

修饰类

当final修饰类时,该类不能被继承。

定义类,在class前加final

创建对象时的内存变化

Object类

是java中所有类的父类。每个类都是这个类的子类,但没有使用extends体现出来

该类中定义了很多方法,通常需要进行重写。

对象造型/对象转型/cast

类似于原始类型中的数据类型转换。对象A转换为对象B的过程,称为对象转型。

在非继承关系的两个对象中,无法转型。

向下转型

父类对象转换为子类对象的过程,称为向下转型。强制转换

向上转型

子类对象转换为父类对象的过程,称为向上转型。自动转换

重写equals方法

//一个父类对象

Object obj = new Object();

//默认无法直接将obj使用Person对象接收

//"强制转换"

Person p = (Person) obj;

//一个子类对象

Person p = new Person();

//默认子类对象可以用父类变量接收 多态

Object obj = p;如果两个对象的属性全部相同,在日常的业务逻辑中,可以视为这两个对象是同一个对象。

但是默认使用new创建的对象,就算属性一致,也是不同的内存地址,

如果用==比较,比较的是对象的内存地址,地址不同,返回false。

所以对象比较相同不能使用==

这时就需要自定义一套比较的方法,Object中有一个equals方法,用于比较两个对象是否相同,

但是Object中的equals方法用==比较,所以对该方法进行重写。

如两个Student的id、name、sex都一致,返回true.

在IDEA中自动生成equals方法

在类中右键generate或快捷键alt + insert,选择equals and hashcode,选择属性。

如两个对象的id相同就视为同一个对象,可以只选择id属性;

如两个对象的所有属性相同才视为同一个对象,选择全部属性。

同时生成的hashcode()可以删除。

面向对象三大特性--多态

子类的对象保存在父类的变量中。

父类 变量 = new 子类();

多态的应用

当某个方法的参数为父类变量时,可以传递一个子类对象。

这样就能在传递不同的子类对象时,表现出不同的形态。

如 要定义动物发出叫声的方法,参数是猫,输出猫对象的叫的方法"喵喵",参数是狗,输出狗对象的叫

的方法"汪汪"。

不用多态,需要写很多重载的方法,参数为猫或狗或其他类型。

使用多态,只需一个方法,参数为动物类,在动物类中定义叫的方法,让子类猫类狗类对其进行重写。

这时调用动物的叫的方法,实际会根据动物子类对象,调用具体子类重写后的方法。

多态的前提

在继承关系中

父类的变量保存子类的对象(向上转型)

abstract抽象的

修饰方法

使用:访问修饰符 abstract 返回值类型 方法名(参数列表);

如果一个方法的方法体无法描述,是由其子类进行重写后使用,可以将这个方法定义为抽象方法。

该方法就可以去掉方法体部分,该方法的所在类,也必须是一个抽象类,使用abstract修饰。

修饰类

使用:访问修饰符 abstract class 类名{}

如果一个类中有抽象方法,这个类必须也是一个抽象类

abstract关键字特点

修饰类:被修饰的类称为抽象类

抽象类不能被实例化(不能创建对象);

抽象类中有构造方法,在创建其子类对象时自动调用。

抽象类中可以有普通方法,通过其子类对象主动调用。

抽象类中定义的所有抽象方法,子类要么全部进行重写,要么也定义为抽象类。

修饰方法:被修饰的方法称为抽象方法

抽象方法没有方法体

抽象方法只能出现在抽象类中

abstract不能修饰构造方法和静态方法

抽象相关面试题

抽象类的特点?

抽象类是使用abstract修饰的类,除了不能创建对象、能定义抽象方法外,与普通类一样。

抽象方法的特点?

抽象方法是使用abstract修饰的方法,没有方法体。非抽象子类必须要对父类中的抽象方法进

行重写。

//当一个类中有抽象方法时,这个类也必须是抽象类

public abstract class Fruit{

//当一个方法没有方法体时,这个方法定义为抽象方法

public abstract void eatIt();

}抽象类中有构造方法吗?

有构造方法,但不是通过new该类对象时调用,而是在new其子类对象时自动调用。

执行某个类的构造方法时,一定会创建这个类的对象吗?

不一定

如果是普通类,在执行构造方法时,一定会创建对象

如果是抽象类,在执行构造方法时,不会创建自身对象,只会创建其子类对象

接口interface

在Java中,数据类型分为基本类型和引用类型。

引用类型包含:数组、类和接口。

所以接口是一种数据类型,类似于类,在定义接口的时候,使用interface替换class。

由于Java是单继承,如果类A既要继承类B中的内容,也要继承类C中的内容时,

如果用"extends class名",只能选择一个类继承,

但使用implements interface名1,interface名2...就能同时"继承"多个"父类".这里的"父类"就是接口。

通常用extends表示类A继承类B,用implements表示类A实现接口A,接口B...

一个类可以同时implements实现("继承")多个接口。

extends和implements

类A extends 类B

类A当做类B的子类,称为继承

类A implements 接口A,接口B...

类A当做类B的实现类,称为实现

接口A extends 接口B

接口A继承接口B类A extends 类B implements 接口A,接口B...

类A是类B的子类,同时也是接口A,接口B的实现类

什么时候使用接口

如果想要让某个类作为多个"类"的子类时,将这些"父类"定义为接口

如果某个类中的所有方法都是抽象方法时,将这个抽象类改为接口

定义接口

抽象类和接口的异同

抽象类是一个类,用abstract class定义

有构造方法,不能创建对象,在创建子类对象时自动调用父抽象类中的构造方法

抽象类中可以有非抽象方法

抽象类被子类继承时,用extends关键字。子类需要重写父抽象类中的所有抽象方法

子类只能继承一个抽象类

抽象类中可以定义成员变量

接口不是一个类,用interface定义

没有构造方法,不能创建对象

接口中定义抽象方法时,无需加public abstract修饰符

接口中可以存在被default或static修饰的方法

接口被子类实现时,用implements关键字。子类需要重写父接口中的所有抽象方法

子类可以实现多个接口,用逗号隔开

接口中定义的属性都是公共的静态常量,被public static final修饰,必须要有初始值

相同点

接口和抽象类都无法创建对象

接口的实现类和抽象类的子类,都需要重写抽象方法

接口是一个完全抽象类。JDK1.8之后可以在接口中定义有方法体(被default或static修饰)的方法。

package com.hqyj.test3;

/*

* 模拟电脑使用USB设备

* 主机都有"USB接口",定义主机类,定义一些方法,参数为"USB设备"

* 所有“USB设置”都有连接和退出功能

*

*

* */

public class Main {

public static void main(String[] args) {

Computer computer = new Computer();

//接口对象无法实例化(无法创建对象)

//USB usb = new USB();

//创建接口的实现类对象,可以用自身接收,也可以用父接口变量接收

Mouse mouse = new Mouse();

USB keyboard = new Keyboard("罗技");

computer.powerOn(mouse, keyboard);

//可变参数的方法传递参数时,可以是任意数量个参数,但这些参数类型必须统一

computer.powerOff(mouse,keyboard);

}

static静态的

每次new创建一个对象,都会在堆空间中开辟一块区域,这个过程是需要花费时间和空间的。

在栈空间中,只会定义变量,保存堆空间中某块区域的地址。通过变量访问堆空间中对应地址的数据。

如果多个对象都有相同的属性或方法时,可以将这些公共的属性和方法使用static修饰,

让其成为静态数据,在类加载的时候就保存在静态区中

在不使用静态成员时

如上图的"重庆大学"这个字符串,每个对象都会使用,就可以将其使用static关键字,定义为静态属性。

静态属性或静态方法,在类加载时就会保存到内存中,无论是否创建对象都能访问,通过类名直接访

问。

使用静态成员时

概念

static是一个修饰符,可以修饰属性、方法、代码块。

被static修饰的内容,称为静态成员。静态成员在类加载时就保存到内中。

访问静态成员时,可以不用创建对象,直接通过类名访问。

如Math中的所有属性和方法,都是静态的,都通过Math直接访问。

定义和访问

什么时候使用static

如果某个属性或方法被高度重用时,可以将其定义为static静态的。

这样这些属性和方法在类加载时就会加载到内存中,从而直接通过类名即可访问。

static特点

静态方法中只能使用静态成员,不能使用非静态成员

非静态方法中,可以访问非静态或静态成员

静态方法中不能使用this或super关键字

成员变量、局部变量、静态常量

成员变量:定义在类中的变量

成员变量随着对象的创建而存在,随着对象的回收而销毁。

作用范围在类内部,成员变量有初始值。

局部变量:定义在方法中的变量

局部变量随着方法的调用而存在,随着方法执行结束而销毁。

作用范围在方法内容,局部变量没有初始值,必须赋值后才能使用。

静态常量:被final、static修饰的成员变量

静态常量随着类加载而存在,随着类的销毁而销毁(通常程序运行结束).

作用范围在程序运行周期中,静态量有初始值,静态常量必须赋值。

可变参数

当某个方法的参数是同一种类型且数量未知时,参数列表中可以使用可变参数定义

特点

可变参数只能出现一次,且是最后一个参数

可变参数实际是一个数组

调用参数为可变参数的方法时,传递的实参要使用逗号隔开

枚举

Java中的枚举是一个特殊的类,是一些常量的集合。

如星期可以用数字1-7表示,也可以用"周一到周天"表示,

也可以用SUN,MON,TUE,WED,THU,FRI,SAT这些来表示。

这三种都可以称为枚举,对星期这个概念进行枚举。

定义枚举类型

内部类

内部类,是指定义在类中的类。

内部类通常使用private修饰,定义在类中,用于隐藏类的实现细节,将类进行封装

内部类分为:成员内部类,静态内部类,局部内部类和匿名内部类。

匿名内部类

没有名称的内部类称为匿名内部类。

当某个方法的参数为接口或抽象类对象时,通常会先定义接口的实现类或抽象类的子类,再创建子类对

象作为方法的参数。

如果使用匿名内部类,就可以不用创建子类,而是直接通过匿名内部类作为参数使用。

Lambda表达式

JDK8中的核心升级点。

通常用于简化匿名内部类的写法。

要简化的匿名内部类必须是函数式接口(只有一个抽象方法的接口)。

Lambda表达式语法

(参数类型 参数名) -> {代码语句;}

小括号部分表示参数列表

->部分表示要执行什么

{}部分表示执行的内容

面向过程和面向对象编程思想

面向过程POP:所有步骤按顺序执行,注重执行的细节。

面向对象OOP:创建解决问题的对象,让各个对象调用各自的方法而配合完成。

在面向对象编程OOP中,给类中定义的方法,具体的实现过程,其实也是面向过程的。

对象和类

对象Object

某个类的具体实例

类Class

是拥有相同属性和行为的对象的集合。是对象的模板。

定义类

类中的属性

成员变量、局部变量、静态常量

成员变量:定义在类中的变量,即类的属性。它有默认值。通过对象访问。

局部变量:定义在方法中的变量。它没有默认值。只能在方法中赋值后才能使用。

静态常量:特殊的成员变量,用final static修饰。它有默认值。通过类名访问。

类中的方法

构造方法

成员方法

静态方法

创建对象

构造方法

是一种特殊的方法。方法名和类名一致,没有返回值部分。

没有返回值部分,方法名必须和类名一致。

在使用new关键字创建对象时,调用对应的构造方法。

每个类在定义后,都隐藏有一个无参的构造方法。

如果自定义了有参数的构造方法,无参数的构造方法就会失效。如果想要使用无参构造方法,就要

再写出来。

构造方法通常用于限制创建对象时携带的参数,初始化成员变量。

构造方法之间都是重载关系,构造方法不能重写。

构造方法执行时,不一定会创建对象。如抽象类中有构造方法,但无法创建抽象类对象,只能在创

建抽象类的子类对象时,自动调用抽象类的构造方法。

面向对象三大特性

封装

将类中的属性使用private修饰,这样就能防止非当前类对其访问,隐藏类中的关键属性。

通常会对private修饰的属性提供公开的get和set方法用于获取和赋值。

继承

类A extend 类B。

接口A extends 接口B。

前者就是后者的子类,前者的对象就能直接访问后者中非私有成员。

重写Override

子类继承父类后,对父类中的非私有方法进行重写,达到拓展或重做的目的

必须满足方法名、返回值、参数列表都相同

访问权限不能比父类中的方法更严格

不能抛出比父类中的方法更大的异常

重载Overload

在一个类中,某个方法在不同的参数下,表现不同的行为。同名不同参。

方法名必须相同

参数列表必须不同(类型和数量)

无返回值无关

this和super

都可以当做对象后构造方法使用。

当做对象:this表示当前类的对象,super当前类的父类对象。

this或super当做对象使用时,只能用在非静态方法中。

当做构造方法

this()表示当前类中无参构造方法,如果带参数就表示对应参数的构造方法

super()表示当前类的父类的无参构造方法,如果带参数就表示对应参数的构造方法

this()或super()只能用在另一个构造方法的首行。

在继承后,如果子类和父类都没有写出任何构造方法时,子类中有一个隐藏的无参构造方法,会自动调

用父类的无参构造方法

所以如果在父类中定义了有参数的构造方法,无参构造方法就会失效,子类必须调用父类中的有参数的

构造方法

Object类

是所有类的父类。任何类都间距地继承了Obejct类。所以所有类都能访问Object类中的方法,都可以进

行重写。

toString()是Object类中的一个方法,在输出对象时自动调用。

默认输出"类全限定名@十六进制哈希码"。通常在自定义的实体类中,重写toString(),输出当前类

的属性。

equals()是Object类中的一个方法,用于比较两个对象是否相同。

默认使用==比较内存地址。通常在自定义的实体类中,重写equals(),自定义比较的规则。

hashCode()是Object类中的一个方法,用于获取对象的哈希码。

默认使用全部参数生成哈希码。可以重写自定义生成哈希码的参数。

对象转型

类似于原始类型间的数据类型转换

向上转型:父类变量 = 子类对象;

类似于自动类型转换

向下转型: 子类变量 =(子类) 父类对象;

类似于强制类型转换

多态

在继承关系中,子类的对象可以保存到父类的变量中。(向上转型)

多态常用与定义方法时,形参为一个父类或接口类型变量,实参为子类对象。

无法通过父类变量调用子类中独有的方法。如果调用重写了父类中的方法时,执行重写后的内容

修饰符

访问修饰符

修饰属性

变量变为常量,定义时就要赋值,程序运行过程中不能改变其值。

修饰方法

方法成为最终方法,不能重写。

修饰类

类为最终类,不能被继承。

abstract

修饰方法

方法为抽象方法,没有方法体。同时所在的类也需要使用abstract定义为抽象类

修饰类

抽象类不能创建对象

抽象类除了能定义抽象方法外,其余与普通类无区别

抽象类中可以有构造方法,在创建其子类对象时自动调用

抽象类通常需要被继承,一旦有子类继承,子类就要重写抽象父类中的所有抽象方法,或者子

类也是一个抽象类

interface

用于定义接口的关键字。代替class,能让java实现"多继承"。

如果某个抽象类中的所有方法都是抽象方法时,可以将该类改为接口。

abstract class --> interface

接口是一个完全抽象类,其中的方法都是public abstract修饰的抽象方法,其中的属性都是public

final static修饰的静态常量。

接口中没有构造方法,不能创建对象

接口通过implements“继承”。类A implements 接口A,接口B,称为类A实现了接口A和接口B,一

个类可以"继承"多个父接口

一个类一旦实现了某个接口,就要重写其中的所有抽象方法

JDK1.8后,可以在接口中定义default或static修饰的方法,该方法不用重写。

static

被static修饰的内容称为静态成员

静态成员在类加载时就会保存到内存中,所以访问时通过类名直接访问。

当某个属性或方法被高度重用时,将其定义为静态的,之后通过类名方便调用。

修饰方法

修饰属性

定义代码块

个人小项目

面向对象综合练习--简易xxx管理

功能:

实现对图书的添加、修改、删除、查询功能

如何保存多个图书?

采用图书数组保存

如何实现添加?

判断数组是否有空元素(元素==null),如果有,将参数对象保存

如何实现删除?

遍历数组,根据参数编号循环比较,如果满足相等,用null覆盖

如何实现查询?

查询所有

遍历数组,空元素无需打印

查询单个

根据编号与数组中的元素遍历比较,满足时返回对应的对象

如何实现修改?

调用查询单个的方法,得到编号对应的对象,使用set方法对某个属性赋值

图书类Book

package test4;
/*
* 图书类
* 编号
* 书名
* 作者
* 类型
* 出版社
* 价格
*
* 定义私有属性
* 自动生成全参构造方法、无参构造方法、getter/setter、toString()
* */
public class Book {
private int id;
//封装属性
private String name;
private String author;
private String type;
private String publisher;
private double price;
//用于输出对象时自动调用
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", author='" + author + '\'' +
", type='" + type + '\'' +
", publisher='" + publisher + '\'' +
", price=" + price +
'}';
}
//封装:getter/setter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
管理员类Manager
//无参数的构造方法
public Book() {
}
//全部参数的构造方法
public Book(int id, String name, String author, String type, String
publisher, double price) {
this.id = id;
this.name = name;
this.author = author;
this.type = type;
this.publisher = publisher;
this.price = price;
}
}

管理员类Manager

package test4;
/*
* 图书管理员类
* 属性
* 保存图书的容器
*
*
* 方法
* 增 添加图书
* 删 删除图书
* 改 修改图书
* 查 查看图书
*
* */
public class Manager {
//保存图书对象的容器,该属性只能当前类使用,使用private修饰,不提供get/set
private Book[] bookList = new Book[10];
//添加
void addBook(Book book) {
for (int i = 0; i < bookList.length; i++) {
//如果存在空位,将参数保存在该位置上
if (bookList[i] == null) {
bookList[i] = book;
//停止循环,防止装满
break;
}
}
}
//查看所有图书
void showAll() {
System.out.println("编号\t书名");
for (Book book : bookList) {
if (book != null) {
//只显示编号和书名
System.out.println(book.getId()+"\t"+book.getName());
}
}
}
/*
* 根据id修改价格
* */
void update(int id,double newPrice){
//根据id得到对应的图书
//调用当前类中定义的根据id查询Book对象的方法
Book book = getBookById(id);
//判断是否得到
if(book!=null){
book.setPrice(newPrice);
}else{
System.out.println("图书不存在");
}
}
/*
* 根据图书编号删除
* */
void delete(int id) {
//遍历数组
for (int i = 0; i < bookList.length; i++) {
//bookList[i]是数组中的某个book对象
//如果该对象不为空,获取其id与参数判断
if(bookList[i]!=null && bookList[i].getId()==id){
//使用null覆盖,实现删除
bookList[i]=null;
break;
}
}
}
/*
* 根据id得到对应的图书对象
* */
Book getBookById(int id) {
//遍历当前所有的图书对象
for (Book book :bookList) {
//如果遍历出的对象不为空,得到对应的id与参数判断
if (book!=null && book.getId()==id) {
//返回对应的图书
return book;
}
}
//如果遍历未发现满足条件,返回null
return null;
}
}

程序入口类Main

package test4;
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//创建管理员对象
Manager manager = new Manager();
while (true) {
System.out.println("请选择功能:1.添加图书\t2.修改图书\t3.删除图书\t4.查看所
有图书\t5.查看图书详情\t6.退出");
switch (sc.nextInt()) {
case 1:
int id = new Random().nextInt(9000) + 1000;
System.out.println("请输入书名");
String name = sc.next();
System.out.println("请输入作者");
String author = sc.next();
System.out.println("请输入类型");
String type = sc.next();
System.out.println("请输入出版社");
String publisher = sc.next();
System.out.println("请输入价格");
double price = sc.nextDouble();
//创建一个图书对象
Book book = new Book(id, name, author, type, publisher,
price);
//调用添加方法
manager.addBook(book);
break;
case 2:
System.out.println("请输入要修改的编号");
int updateId = sc.nextInt();
System.out.println("请输入要修改的价格");
double newPrice = sc.nextDouble();
manager.update(updateId, newPrice);
break;
case 3:
System.out.println("请输入要删除的编号");
manager.delete(sc.nextInt());
break;
case 4:
manager.showAll();
break;
case 5:
System.out.println("请输入要查看的编号");
System.out.println(manager.getBookById(sc.nextInt()));
break;
case 6:
System.exit(0);
break;
}
面向对象三大特性--继承
概念
类B使用extends(延伸)关键字"继承"类A。
语法:class 类B extends 类A{}
类B称为类A的子类,衍生类,subClass
类A称为类B的父类,超类、supClass
继承后,子类就能访问父类中的非私有(没有使用private修饰)成员变量和成员方法。
将多个类中的公共代码提取出来保存到一个公共类中,这些类使用extends"继承"这一个公共类,从而减
少这些类中的冗余代码。
如猫类、狗类都有类型、昵称等属性,也有吃、睡等方法,那就可以定义一个动物类,将这些公共的属
性和方法定义在动物类这个父类中,
再让猫类和狗类这些子类继承动物类。这样就能直接通过子类访问父类中的内容。
特点
如果多个类之中有相同的代码,可以将这些代码提取出来到一个公共的类中,这个类就是父类。再
让那些类去extends继承这个父类,那些类就是子类。子类就无需再写重复代码
子类中或子类对象可以直接访问父类中非私有(不用private修饰)属性和方法
}
}
}

个人心得

这个阶段的概念知识点比较多,而且也不易理解,所以在学起来比较吃力,要学好这部分要充分理解,面向对象和面向过程,而且要对这部分代码要有足够的熟练度,然后对封装,继承,多态去深刻的理解。对每个项目的每一步都要去用逻辑分析,然后合理的写出每一步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值