从零开始学Java-面向对象

159 阅读12分钟

目录

  • 面向对象
  • 类和对象
  • 封装
  • this关键字
  • 构造方法
  • 标准JavaBean
  • 对象内存图

什么是面向过程

我们来找个例子吧:(洗衣服)

我们面向过程的设计就是把打开洗衣机,把洗衣粉放进去,把水放入,放入衣服,开始洗衣。

而我们如果使用面向对象的方式去定义时,衣服和洗衣机分别是一个对象,洗衣机的开门,蓄水,洗衣,可以作为洗衣机的行为,那么洗衣机就是一个对象,洗衣机通过他的开门的行为,让衣服,放入,洗衣机自动蓄水,洗衣机自动洗衣。这样就是简单的面向对象和面向过程的对比。

类和对象

  • 类:是对象共同特征的描述。
  • 对象:是真实存在的具体对象。

在Java中,必须先设计类,才能获得对象

  • 定义类:

image.png

成员变量完整格式:修饰符 数据类型 变量名称 = 初始化值

(一般不用初始化,真正创建对象了在给对象赋值)

// 属性  实例类
String breand; // 成员变量 (代表属性的,一般是名词)
double price; // 成员方法 (代表行为的,一般是动词)

public void call() {
    System.out.println("手机在打电话");
}
public void playGame() {
    System.out.println("手机在玩游戏");
}
  • 创建对象:

创建好了类之后就可以使用对象了:类型 对象名 = new 类名();

image.png

  • 使用对象:
    • 访问属性:对象名.成员变量
    • 访问行为:对象名.方法名(...)
// 创建手机的对象
Objectdemo1 p = new Objectdemo1();

// 给手机对象赋值
p.breand = "华为";  // 对字段 breand 赋值
p.price = 1999.99;  // 对字段 price 赋值

// 调用手机中的方法即可
p.call();
p.playGame();
  • 注意事项:

    • 1.用来描述一类事物的类,专业叫做:Javabean类

    (在Javabean类中,是不写main方法的。)

    • 2.之前编写main方法的类,专业叫做:测试类

    (在测试类中,可以创建Javabean类的对象进行赋值调用。)

    • 3.类名首字母建议大写,英文,有意义,满足驼峰模式,不能是关键字,满足标志符规定
    • 4.一个代码文件中可以定义多个类,但是只能一个类是public修饰的。

封装

封装是面向对象的三大特征之一:封装、继承、多态\color{red}{封装、继承、多态}

那什么是封装呢:封装就是告诉我们拿到一个需求之后如何正确设计对象的属性和方法。 image.png 我们来思考一下,人关门,这个门是人关的还是门自己关的呢?

其实这个门是自己关的,为什么呢?我们来想一下。人干了什么事,门干了什么事?

是不是我们人给了门一个作用力,门自己关起来了,使用呀关门这个方法一定是门的方法,而不是人的。

原则:对象代表什么,就得封装对应的数据,并提供数据对应的行为。

下面我们来说一下封装的好处吧:

1. 让编程变得简单,有什么事找对象,调方法就行。

2. 降低我们的学习成本,可以少学、少记,有需要的时候去找就可以了。

下面我们就来说一下属性和行为封装在对象中之后该如何去描述代码才是安全、健壮、优雅的!

如何正确设计对象的属性和方法

我们来举个例子:

image.png

这个时候我们来给age赋值:p.age = -18,代码语法是不是没有问题,但是和实际情况不符合。那怎么办呢?

我们来说一下private关键字修饰符:

  • private关键字\color{red}{private关键字}
    • 是一个权限修饰符。
    • 私有关键字,不让外界访问。
    • 可以修饰成员。(成员变量和成员方法)
    • 被private修饰的成员只能在本类中才能访问。
    • 针对private修饰的成员变量,如果需要被其他类使用,需要提供相应的操作。
    • 提供"setXxx(参数)"方法,用于给成员变量赋值,方法用public修饰。
    • 提供"getXxx()"方法,用于获取成员变量。方法用public修饰

image.png

我们来实操一下:首先给每个属性加上私有修饰符。

// 属性
private String girName;
private String girsex;
private int age;
private double height;

针对于每一个私有的成员变量,都要提供get和set方法

set()方法\color{red}{set()}方法:给成员变量赋值

// 作用:给成员变量girName进行赋值
public void setName(String n){
    girName = n;
}
// 作用:给成员变量girsex进行赋值
public void setSex(String n){
    girSex = n;
}
// 作用:给成员变量age进行赋值
public void setAge(int n){
    if(n >= 18 && n<= 25){
        girAge = n;
    }else{
        System.out.println("非法年龄!");
    }
}
// 作用:给成员变量height进行赋值
public void setHeight(double n){
    girHeight = n;
}

get()方法\color{red}{get()}方法:对外提供成员变量的值

// 作用:对外提供girName属性的值
public String getName(){
    return girName;
}
// 作用:对外提供girsex属性的值
public String getSex(){
    return girSex;
}
// 作用:对外提供age属性的值
public int getAge(){
    return girAge;
}
// 作用:对外提供height属性的值
public double getHeight(){
    return girHeight;
}

我们来给对象赋值吧:使用set()方法\color{red}{set()}方法!用于给成员变量赋值

// 给对象赋值
p.setName("小诗诗"); // 对字段 girName 赋值
p.setSex("女");// 对字段 girsex 赋值
p.setAge(18);// 对字段 age 赋值
p.setHeight(170.0);// 对字段 height 赋值

赋值完毕就要获取啦:使用get()方法\color{red}{get()方法}!用于获取成员变量

String Name = p.getName();
System.out.println("姓名:" + Name);
String Sex = p.getSex();
System.out.println("性别:" + Sex);
int Age = p.getAge();
System.out.println("年龄:" + Age);
double Height = p.getHeight();
System.out.println("身高:" + Height);

到这里我们的private关键字学完啦,使用private的关键字是为了保证数据的安全性,如果不加可能会在外面传递一些非法的数据过来,加了外部就不能直接调用啦!

this关键字

  • this的作用:区分局部变量和成员变量!\color{red}{区分局部变量和成员变量!}
  • this的本质:所在方法调用者的地址!\color{red}{所在方法调用者的地址!}

我们来看个案例:

private int age = 20; // 成员变量

public void method(){
    int age = 10;  //  局部变量
    System.out.println(age);
}

这个时候我们打印age是多少呢?我们运行看一下: image.png

是不是打印出10呀!

为什么呢?因为当成员变量和局部变量重名的时候就会触发就近原则,谁离我近,我就用谁。那我们想用成员变量怎么办呢?很简单,我们加上this. 前缀就可以了,我们来看一下:

System.out.println("当前打印的是:" + this.age);

image.png

是不是把成员变量给打印出来了呀。

我们来总结一下吧:就近原则\color{red}{就近原则}

System.out.println(age);

这行代码没有this.前缀,所以他会先到局部位置去找,如果局部位置没有才会到成员变量去找。

System.out.println(this.age);

这行代码有this.所以他不会到局部位置去找,而是会直接去成员变量找

构造方法

主要掌握:构造方法的格式以及构造方法的作用

  • 构造方法概述:
    1. 构造方法也叫构造器\color{red}{构造器}*、构造函数\color{red}{构造函数}

    2. 作用:在创建对象的时候给成员变量进行初始化\color{red}{初始化}的。

  • 构造方法的格式:

image.png

如果我们自己没有写任何的构造方法,那么虚拟机会给我们加一个空参构造方法。

  • 空参构造方法初始化:
public Objectdemo4(){
    System.out.println("看看我执行了吗");
}
  • 空参构造方法调用:
// 调用空参构造
Objectdemo4 p = new Objectdemo4();
  • 带参构造方法初始化:
  • 赋值:创建对象的时候系统会根据你后面的参数自动调用构造方法赋值。
// 带参构造方法
public Objectdemo4(String name,int age){
    this.name = name;
    this.age = age;
}
  • 带参构造方法调用:这个时候括号里面就要带参数了。
// 调用带参构造
Objectdemo4 p = new Objectdemo4("zhangsan",18);

我们来获取一下里面的值吧!利用get方法获取。

// 获取值
System.out.println("姓名:" + p.getName() + "\n" + "年龄:" + p.getAge());

有人就会问了,那我是不是不用空参构造了呢?我直接用带参构造不就好了吗?

其实呀,一般都是会写空参和带参构造,因为有时候我们在创建对象时不知道属性值的,这个时候我只能用空参构造先把对象创建出来,等用户键盘录入后等有值了在通过set方法进行赋值。

下面我们就来总结一下构造方法吧:

  • 执行时机\color{red}{执行时机}

    1.创建对象的时候由虚拟机调用,不能手动调用构造方法。

    2.每创建一次,就会调用一次构造方法。

  • 构造方法的作用\color{red}{构造方法的作用}

    1.创建对象的时候由虚拟机自动调用作用就是给成员变量进行初始化的

  • 构造方法有几种,各自作用\color{red}{构造方法有几种,各自作用}

    无参数:初始化对象时,成员变量的数据均采用默认值

    带参数:在初始化时,同时可以为对象进行赋值

  • 构造方法的格式特点\color{red}{构造方法的格式特点}

    1.方法名与类名相同,大小写也要一致。

    2.没有返回值类型,连void都没有。

    3.没有具体的返回值(不能由return带回结果数据)。

  • 构造方法的注意事项\color{red}{构造方法的注意事项}

    定义\color{red}{定义}:1.如果没有定义构造方法,系统将给出一个默认无参数构造方法

    2.如果定义了构造方法,系统将不再提供默认的构造方法。

    3.任何类定义出来默认就带了无参数构造器,写不写都有。

    4.一旦定义了有参数构造器,无参数构造器就没有了,此时就需要自己手写无参数构造器了。

    重载\color{red}{重载}:1.带参数构造方法和无参数构造方法,两者方法名相同,但是参数不同,这也叫构造方法的重载

    推荐使用方式\color{red}{推荐使用方式}无论是否使用,都手动写无参构造方法和带全部参数的构造方法。

标准的JavaBean

  • 标准的JavaBean类

    1.类名需要见名知意。

    2.成员变量必须使用 private\color{red}{private}修饰

    3.提供至少两个构造方法。(无参构造方法、带全部参数的构造方法)

    4.成员方法 (提供每一个成员变量对应的setXxx()/getXxx())

我们来写个案例:

image.png

第一步:是不是要先编写属性

private String name;
private String password;
private String email;
private String gender;
private int age;

第二步:编写空参构造方法

// 空参构造
public UserInfo(){};

第三步:编写带全部参数的构造方法

// 带全部参数构造
public UserInfo(String username,String userpassword,String useremail,String usergender,int userage){
    this.name = username;
    this.password = userpassword;
    this.email = useremail;
    this.gender = usergender;
    this.age = userage;
};

第四步:编写set()方法

// 编写set方法
public void setName(String username){
    this.name = username;
}
public void setPassword(String userpassword){
    this.password = userpassword;
}
public void setEmeil(String useremail){
    this.email = useremail;
}
public void setGender(String usergender){
    this.gender = usergender;
}
public void setAge(int userage){
    this.age = userage;
}

第五步:编写get()方法

// 编写get方法
public String getName(){
    return name;
}
public String getPassword(){
    return password;
}
public String getEmeil(){
    return email;
}
public String getGender(){
    return gender;
}
public int getAge(){
    return age;
}

到这里我们就写好了这个案例啦!是不是感觉一个一个写很麻烦呢?那下面就给大家分享一键生成的快捷键吧!

快捷键:alt + insert / alt + Fn + insert

我们编写好属性后按快捷键alt + Fn + insert。

image.png

选择Constuctor

image.png

这个时候是不是空参构造方法就生成了呢。

image.png

然后接着按快捷键alt + Fn + insert。

image.png

按住SHIFT键全选,然后🆗

image.png

是不是就一键生成带全部参数的构造方法了呀!

image.png

然后还是按快捷键alt + Fn + insert。

image.png

这个时候我们就要选择get和set方法了,而不再是选择第一个了。

image.png

按住SHIFT键全选,然后🆗

image.png

这个时候就把我们属性的set和get方法就一键生成啦,怎么样是不是很方便呢?不过刚入手还是建议手打哟,等后面熟练了在使用快捷键会更好一点呢!

为了更好的理解对象,对象在内存中到底是怎么回事,下面我们来说说对象内存图吧!

对象内存图

我们来看一下下面的图片: image.png

在运行Java的时候,java的虚拟机也会占用一块内存。只不过为了更好的去利用这块内存,这块内存又分为了5部分\color{red}{5部分}。每个部分都有各自的作用,分别如下:

image.png

当我们要运行一个类的时候,这个类的字节码文件就会被存放到方法区里面临时存储。

image.png

下面我们来说说一下内存图吧:

一个对象的内存图

  • 创建一个对象: Object s = new Object();当我们创建他的时候,内存最少会做7件事。

      1. 加载class文件。 //把Object的字节码文件加载到内存。
      1. 申明局部变量。 // 对等号左边的s来进行声明。
      1. 在堆内存中开辟一个空间。 // 等号的右边new出一个空间。
      1. 默认初始化。
      1. 显示初始化。
      1. 构造方法初始化。
      1. 将堆内存中的地址值赋值给左边的局部变量。

二个对象的内存图

两个对象的内存图其实是和一个对象是一样的,只是两个对象就需要操作两次!

基本数据类型和引用数据类型内存图

  • 基本数据类型:整数型、浮点型、字符型、布尔型

  • 引用数据类型:除了基本数据类型其他都是引用数据类型。

我们先来看一下基本数据类型的内存图吧:

int a = 10;
double b = 20;

image.png

这里我们可以得知:基本数据类型存储的是真实的数据值!

特点:赋值给其他变量赋的是真实的值!

再来看一下引用数据类型的内存图吧:

int[] arr = {1,2,3,4};

image.png

而要获取里面的值就需要用到索引来获取

image.png

这里我们可以理解为引用数据类型就是拿别人的东西过来用。这就叫做引用\color{red}{引用}

引用数据类型自己空间存的是地址值。而数据值是存放在其他空间里面的!

特点:赋值给其他变量,赋的不是真实数据,而是地址值!

成员变量和局部变量的区别

  • 什么是局部变量:方法中的变量。\color{red}{方法中的变量。}

image.png

  • 什么是成员变量:类中方法外的变量。\color{red}{类中方法外的变量。}

image.png

  • 我们来看一张图区分两者的区别吧:

image.png

  • 我们来看一下成员变量和局部变量的内存图吧:

    • 局部变量例:
    int a = 10;
    

    image.png

    这个a是在栈里面的,所以是局部变量。\color{red}{局部变量。}

    我们再来看一下成员变量:

    • 局部变量例:
    new Student();
    
    public class Student{
        private String name;
        private int age;
    }
    

    image.png

    这行代码创建了一个Student对象,是在堆里开辟的一个空间。那么这里的nameage他在堆当中,所以是成员变量。\color{red}{成员变量。}

好啦,以上就是Java的面向对象的一些知识,对于刚入手的你是不是觉得有点蒙蒙呢?没事,经过你的多次练习,相信你能做到轻而易举的。有什么不懂的可以在评论区评论哟!我们下期再见!!!

==最后非常感谢您的阅读,也希望能得到您的反馈  ==