Java面向对象编程基础

面向对象编程基础

  • 什么是面向对象?
    • 面向对象的三大特征
    • 小小总结
  • 对象和类
    • 概念
    • 类的定义
      • 属性的定义
  • 内存分析
  • 构造器
    • 对象创建的步骤
    • 构造器的重载
  • 垃圾回收机制(Gabage Collection)
    • 分代垃圾回收机制
  • this关键字
  • static关键字
  • 静态初始化块
  • 参数传值机制
  • 包package
    • package
    • 类的导入
      • 静态导入

什么是面向对象?

面向对象说到底就是就是一种思想,相同的C语言的面向过程也是一种思想。这里我们假设要编写一个学生信息管理系统,如果用面向过程的思想来说就是思考“怎么去实现这个程序”,于是就想出了一些步骤:

1.输入密码
2.修改学生信息
3.读取学生信息
4.······

而如果是面向对象的思想,首先思考的就应该是“怎么设计这个系统”,然后就知道了这个系统主要的就是学生的信息,而学生的信息就由如下对象组成:

1.姓名
2.年龄
3.性别
4.学号
5.······

面向对象可以帮助人们从宏观上把握,从整体上分析整个系统。-----《实战Java程序设计》

但是在面向对象的同时,在具体的实现过程中还是需要面向过程的思想,这是不可被忽视的。面向对象和面向过程(方法的实现)他们是相辅相成的。
Ps.也不知道上面的例子怎么样吧,不知道是说的正确还是不对,若有不对的地方,还请批评指正!

面向对象的三大特征

封装性、继承性和多态性。这三个特征将会在后学学习中掌握。

小小总结

  • 对象也是一种数据结构(对数据的管理模式),是将数据和数据行为放到了一起
  • 在内存上,对象就是一个内存块,存放了相关的数据集合
  • 对象的本质就是一种数据的组织方式
    ----来自《实战Java程序设计》

对象和类

概念

跟着上面的学生例子来,学生很明显就是我们要研究的对象,更具体一点,我们来研究中学生,那么什么样的人是中学生呢?那么在这个总结归纳的过程中我们就可以找到一些特征

  • 穿校服
  • 要参加中、高考
  • 在中学里(当然在学校里还有教职工)
  • ······等等

好了那么我们就抽象出来了中学生的特征,那么进一步总结归纳的话我们就可以得出一个中学生类了,类是对对象的抽象。
对象–Object/instance,类–class 类的对象==类的实例。
对象是我们要具体研究的事物,而类是对对象的抽象

类的定义

类的定义方式

1.
class 类名{
     
	属性
	方法
}
2.
public class 类名{
     //这个类名和源文件的名称要一样,每个源文件必须有且只有一个public class
	class 类名{
     
		...
	}
	...
}

属性的定义

用于定义类或类对象包含的数据。例如一个学生类属性包括姓名,年龄,性别等。

[修饰符] 属性类型 属性名 = [默认值]

话不多说直接上例子更加直观,以下是一个关于学生类的定义和对象的使用:

class School{
     
    String schoolname;
}
public class Student {
     
    String name;
    int age;
    String sex;
    School sch;
    void tell(){
     
        System.out.println("我是"+name+",我"+age+"岁,我来自"+sch.schoolname);
    }
    Student(){
     
    }
    public static void main(String[] args) {
     
        Student stu = new Student();
        stu.name = "杨某人";
        stu.age = 19;
        stu.sex = "男";
        School sc = new School();
        sc.schoolname = "hnust";
        stu.sch = sc;
        stu.tell();
    }
}

另外一种使用方法
在这里插入图片描述在这里插入图片描述
School.java中源代码

public class School {
     
    String schoolname;
}

Student.java中删去School类就可以了。
结果如下
在这里插入图片描述
UML图如下
Java面向对象编程基础_第1张图片

内存分析

这里有些概念是新的,具体的在后学的学习中会了解到,这里弄一个这个是为了配合书籍去加深理解!
JVM的内存分为三个区域:栈(stack)、堆(heap)、方法区(method area)。
:线程私有,不被共享;每个方法被调用都会创建一个栈帧;“先进后出,后进先出”;内存空间连续。
:线程共享;存储创建好的对象和数组;JVM只有一个堆;内存空间不连续。
方法区:线程共享;只有一个方法区;本质上也是堆;存放存储类、常量信息(存放不变和唯一的内容)。
以上面的代码为例:
1.Student stu = new Student();
Java面向对象编程基础_第2张图片
2.到School sc = new School();前
Java面向对象编程基础_第3张图片
3.后续
Java面向对象编程基础_第4张图片
因为刚学不久,所以肯定不会很熟练,这东西先放在这以后在学到相关的东西的时候可以回来看看。
7.3 还有个tell方法,应该是入栈后出栈输出了吧,emmmm…

构造器

上面的实例代码中有个Student(){}是什么呢?其实就是个构造器。构造器也叫做构造方法(是一种特殊方法),用于对象的初始化。构造器名应与类名一样。Java通过new关键字来调用构造器,返回该类的对象

对象创建的步骤

1.分配对象空间,将对象成员变量初始化为0或者空(null);
2.执行属性值得显式初始化;
3.执行构造器;
4.返回对象的地址给相关的变量。

构造器声明如下:

[修饰符] 类名(形参列表){
     
	·····
}

Ps.若是没有定义构造器,则编译器会自动定义一个没有参数的构造函数。

构造器的重载

构造器是一种特殊的方法,与普通的方法一样,他也可以重载。

public class Student {
     
    String name;
    int age;
    String sex;
    void tell(){
     
        System.out.println("姓名:"+name+" 年龄:"+age+"岁 性别:"+sex);
    }
    Student(){
     
    }
    Student(String name, int age, String sex){
     
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    public static void main(String[] args) {
     
        Student stu1 = new Student();
        stu1.name = "小明";
        stu1.age = 20;
        stu1.sex = "男";
        stu1.tell();
        Student stu2 = new Student("小红", 18, "女");
        stu2.tell();
    }
}

Ps.上面代码的关键字this是用于区分属性和形参,this.name是属性,而n是形参
输出如下
在这里插入图片描述

垃圾回收机制(Gabage Collection)

C/C++的内存管理是很令人头疼的,而Java引入了垃圾回收机制,使得内存管理的问题迎刃而解。
在这里其实可以回去看看内存分析的部分,我们在写Java的时候会创建大量的对象,然后由于堆得内存是有限的,若是对象一直增加,那么堆的空间将很快被耗尽,于是回收处理无用对象便很好地解决了这个问题。
对象空间的创建和释放
创建:使用关键字new即可创建对象。
释放:将对象赋值为null即可。
垃圾回收过程
①发现无用对象;
②回收无用对象所占用的内存空间。
垃圾回收机制的相关算法
GC回收判断对象是否“死亡”有两种算法
①引用计数法
②可达性分析

①堆中的每个对象都会带有一个引用计数器,当有引用指向这个对象时计数器+1,而指向这个对象的引用失效(null)时计算器-1,最终如果计数器==0,则认为该对象无用,并进行回收。但是这个算法有个致命的缺点,就是无法处理对象相互引用。下面给出例子:

public class Student {
     
    Student friend;
    public static void main(String[] args) {
     
        Student stu1 = new Student();
        Student stu2 = new Student();
        stu1.friend = stu2;
        stu2.friend = stu1;
        stu1 = stu2 = null;
    }
}

stu1和stu2的计数器不为0,但他们实际上已经无用了,可是无法被识别。
②把所有的引用关系看成一张图,从一个GCroot开始,寻找相对应的引用节点,找到后就继续寻找直到找完,此时剩余的节点就是被作为没有被引用的节点,即无用节点,然后被回收。给出解释图如下
Java面向对象编程基础_第5张图片
在这张图中A、B、C都与GC root有一定的引用关系,故这三个对象是有用的、存活的;而E、E、F、H跟GC root没有引用关系,所以是无用、死亡的对象。

分代垃圾回收机制

不同的对象的生命周期不一,因此有了分代垃圾回收机制。对象有三种状态:年轻代、老年代和永久代。JVM将堆内存划分为Eden、Survivor和Tenured/Old空间。
Java面向对象编程基础_第6张图片
1.年轻代
所有新生成的对象都首先放到Eden区。年轻代的目标就是尽可能快速收集掉那些生命周期短的对象,对应于Minor GC。年轻代区域存满后将放到年老代。
2.年老代
年老代一般都是些生命周期长的对象,在年轻代中经历了N(默认15)次GC后仍存活的对象,就会被放到老年代,当老年代中对象越来越多时要启动Major GC和Full GC进行一次大扫除。
3.永久代
永久代用于存放静态文件,如Java类、方法等。永久代对GC没有什么显著影响。

  • Minor GC:清理年期代区域。Eden区域满了就会触发一次Minor GC,清理无用对象,将有用对象放到Survivor1/2中去。
  • Major GC:清理年老代区域。
  • Full GC:清理年轻代、年老代,成本高,会对系统性能产生影响

this关键字

this的本质是创建好的对象的地址。因为在构造器调用前,对象已经创建,因此在构造器中也可以使用this代表当前对象。关于this的使用在前面的代码中已经提到了,不在累述。

Ps.

  • 程序中产生异义时,应该使用this来指明当前对象。普通方法中,this总是指向调用该方法的对象;在构造器中,this总是指向正要初始化的对象。
  • 使用this调用重载的构造器,避免相同的初始化代码。但只能在构造器中用,且必须用于构造器的第一句。
  • this不能用于static方法中。

static关键字

在类中,用static声明成员变量为静态成员变量,也称为类变量。类变量的生命周期和类相同,在整个程序运行期间内都有效。

  • 类变量是该类的公用变量,属于类,被该类的所有实例共享,在类被载入时显式初始化。
  • 对于该类的所有对象来说,static成员变量只有一份,被该类的所有对象共享。
  • 一般用“类名,类属性/方法”来调用,也可以通过对象引用或类名(不需要实例化)访问静态成员。
  • 在static方法中不可直接访问非static的成员。

例如

public class Student {
     
    String name;
    int age;
    static String schoolname = "hnust";
    public Student(String name, int age){
     
        this.name = name;
        this.age = age;
    }
    public void hello(){
     
        System.out.println("Hello");
    }
    public static void print(){
     
        //hello();报错
        System.out.println(schoolname);
    }
    public static void main(String[] args) {
     
        Student stu = new Student("杨某人",19);
        Student.print();
        Student.schoolname = "HNUST";
        Student.print();
        schoolname = "HUNST == hnust";
        Student.print();
    }
}

输出如图
在这里插入图片描述

静态初始化块

构造器用于对象的初始化。静态初始化块用于类的初始化操作。在静态初始化块中不能直接访问非static成员。例如

public class Student {
     
    String name;
    int age;
    static String schoolname;
    public static void print(){
     
        System.out.println(schoolname);
    }
    public static void main(String[] args) {
     
        Student stu = new Student();
        System.out.println("你好");
    }
    static {
     
        System.out.println("Hello!");
        schoolname = "HNUST";
        print();
    }
}

输出如下
在这里插入图片描述
这里有关的知识点会在后学内容中马上学到。

参数传值机制

看到这里应该就要想起C/C++中的指针和引用了,而在Java中没有,但是我们前面提到了this关键字,this就是用来做这个事情的,例子前面已经有了,不再累述。

包package

可以理解为C/C++中的头文件但又有不同。关于包理解起来并不难。

package

Package用于对类进行管理。package的使用有两个要点:
(1)它通常是类的第一句非注释性语句。
(2)包名用域名倒着写即可,再加上模块名,这样便于内部管理类。
例如下面这个包名

net.csdn.blog;

导入包

package net.csdn.blog;

类的导入

例如之前就有获取键盘的输入我们就用到了Scanner,而要用Scanner就必须导入包java.util中的Scnner类。怎么导入呢?

import java.util.Scanner;

若要导入某个包下面的所有类,即

import java.util.*;//导入该包下所有的类,会降低编译速度,但不会降低运行速度

静态导入

静态导入的作用是导入制定类的静态属性,以便直接使用这些静态属性。例如:

import static java.lang.Math.PI;
public class Test {
     
    public static void main(String[] args) {
     
        System.out.println(PI);
    }
}
//就可以直接输出该包中的PI值了

你可能感兴趣的:(Java学习笔记)