《深度剖析 Java 类与对象:概念、机制与应用》
《深度剖析 Java 类与对象:概念、机制与应用》
引言:类与对象
在本章中,我们将会学习类与对象,这是个很重要的概念,直指JAVA面向对象这一核心思想;
无非就两个问题
①.什么是类?
②.什么是对象?
举个例子:洗衣机

这是过去传统的洗衣方式,可以看到如果我们最后想要完成这个洗衣服,就必须经过这些步骤,这就是面向过程
而JAVA的面向对象是什么?

面向对象关键的在于对象二字,它不关注执行的过程,只看重对象与对象之间相互协作相互运行最后做出结果,面向对象就是看向对象。
在整个JAVA中,万事万物都是对象,他不需要关注过程,回想一下,我们在JAVA中通过导包,可以使用各种方法,这些方法就是封装好的对象,我们直接用,不需要知道为什么,不过大家还是写一下简单的方法,没坏处
我们现在就可以回答一下问题
①.什么是类?
面向过程编程
②.什么是对象?
面向对象编程
注意:面向过程或者面向对象不是指某一种语言,他只是解决问题的方法;
一.关于类
在大致认识对象后,我们需要认识类,比如手上有一个花瓶;

那么问题来了,为什么他是花瓶,不是其他的东西?
有些人奇怪,这是什么问题,但你仔细思考一下,为什么它不是马桶,不是木桶,不是其他各种东西。


你看到的第一眼就知道这个对象是什么,是不是因为它长的就是你所熟知的那个物品,“长的像”,是一个特征;
对于花瓶我们可以用它的特征来给别人讲述
木桶,马桶等所有对象都有着自己的特征,就是因为它们有属于它们的特征,我们才能认识它们,万事万物都可看做一个对象,人也可以看作,你的亲人,你的朋友不就是靠着特征来辨认的
而在JAVA中我们用类来描述这些特征,不过类中的我们不叫特征,这太俗了,我们叫做**属性/字段**
类的作用:类就是来描述对象的
1.1类的定义
class Student {
// 成员变量
public String name;
public int age;
public float score;
public String classNum;
public void Func1()
{
System.out.println("这是类中的一个成员方法");
}
}
这就是一个最基本的类,包含成员变量还有成员方法,其实还有构造方法,我们后面讲;
关于类的定义,还有很多细节问题,现在先对类了解一下;
1.2类的实例化
有了类,那我们该怎么做,就用到了类的实例化,通过引用将我们写的类实例化,就可以用了;
package bo_ke1;
class Student {
// 成员变量
public String name;
public int age;
public float score;
public String classNum;
public void Func1()
{
System.out.println("这是类中的一个成员方法");
}
}
public class testDemo {
public static void main(String[] args){
Student student1 = new Student();
// 类外赋值
student1.name = "zhan san";
student1.age = 12;
student1.score = 70.1F;
student1.classNum = "1班";
// 通过引用来打印类中成员变量
System.out.println(student1.name);
System.out.println(student1.age);
System.out.println( student1.score);
System.out.println(student1.classNum);
System.out.println("==================");
//调用成员方法
student1.Func1();
}
}

严格来说,JAVA代码规定,一个JAVA文件中只能有一个类,因为刚说,为了让人看得清楚,就先这样写,得到继承多态的时候就会有意识的分开写;
注意:通过类的实例化我们是可以建立多个引用,实例化对象是可以有多个的,对象的特征属性已经通过类描述好了,就是通过实例化来进行运用
package bo_ke1;
class Student {
// 成员变量
public String name;
public int age;
public float score;
public String classNum;
public void Func1()
{
System.out.println("这是类中的一个成员方法");
}
}
public class testDemo {
public static void main(String[] args){
// 学生1
Student student1 = new Student();
// 类外赋值
student1.name = "zhan san";
student1.age = 12;
student1.score = 70.1F;
student1.classNum = "1班";
// 通过引用来打印类中成员变量
System.out.println(student1.name);
System.out.println(student1.age);
System.out.println( student1.score);
System.out.println(student1.classNum);
student1.Func1();
System.out.println("==================");
//调用成员方法
// 学生2
Student student2 = new Student();
// 类外赋值
student2.name = "li si";
student2.age = 15;
student2.score = 80.1F;
student2.classNum = "1班";
// 通过引用来打印类中成员变量
System.out.println(student2.name);
System.out.println(student2.age);
System.out.println( student2.score);
System.out.println(student2.classNum);
}
}
第一个学生student1
Student student1 = new Student();
第二个学生student2
Student student2 = new Student();
还可以继续实例化多个学生
1. 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.
2. 类是一种自定义的类型,可以用来定义变量.
3. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
4. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东
西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空
间
记住实例化出来的东西,才是实际的;

二.类的初始化
2.1构造及初始化
构造
我们要知道一个新东西构造方法,在JAVA类中有两个必须存在:
①:类的属性/字段(成员变量)
②:类的成员方法
这里的构造方法也是属于成员方法,而且是必须存在的
我们先看一个猫类
Cat
public class Cat {
public String name;
public int age;
public Cat()
{
System.out.println("这是一个构造方法");
}
}
再来个测试类(在同一个包中)
public class testDemo {
public static void main(String[] args){
Cat cat = new Cat();
}
}

从运行结果上看,构造方法被执行了,在类的实例化的时候,构造方法就执行了
构造是一定要有的吗?
不知道有人注意到,之前规定的学生类没有构造方法,但好像可以运行;
其实他是有构造方法的,在创建这个类的时候,如果程序员没有写出构造方法,编译器会默认给一个构造方法,这个构造方法的内容是空的,它的参数也是空的;
public Cat() {
}
这就是默认的构造方法;
那如果我们自己写了个构造方法,编译器还会给吗?
不会,它是帮急不帮穷,你没写,但要用,就给你提供一个构造方法,你有了,哪怕在垃圾的构造方法,它也不会帮你写;
初始化
构造方法的作用是初始化;
public class Cat {
public String name;
public int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
}
有些先不要管,这里要知道构造是用来初始化的,看一下测试类,到底有没有初始化;
public class testDemo {
public static void main(String[] args){
Cat cat = new Cat("mi mi",6);
System.out.println(cat.name);
System.out.println(cat.age);
}
}

可以看到我们在类的实例化的时候,通过构造方法来进行初始化;
一个类中可以有多个构造方法:
public class Cat {
public String name;
public int age;
//构造方法1
public Cat() {
}
//构造方法2
public Cat(String name) {
this.name = name;
}
//构造方法3
public Cat(int age) {
this.age = age;
}
//构造方法4
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
}
这是不是有些熟悉,这是方法重载
注意:
很小的细节,对学习这章没多大阻碍
我们把这些叫做初始化,其实叫准确一点,这是修改值
在类中成员创建的时候,就已经初始化了,叫做默认初始化
这个初始化在JVM中实现,一下就是默认初始化的值

就是各个数据类型0的不同形式
2.2就地初始化
就地初始化就是在变量创建的时候,给它赋值;
public class Cat {
public String name = "mi mi";
public int age = 6;
//构造方法1
public Cat() {
}
//构造方法2
public Cat(String name) {
this.name = name;
}
//构造方法3
public Cat(int age) {
this.age = age;
}
//构造方法4
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
}
测试
public class testDemo {
public static void main(String[] args){
Cat cat = new Cat();
System.out.println(cat.name);
System.out.println(cat.age);
}
}
这个很简单,不在讲
三.this引用
3.1this意义
这个前面出现过,他代表什么意思
来,先创建一个狗类,后面慢慢加;
一.加this情况
public class Dog {
public String name;
public int age;
}
这个时候看一下构造方法:
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
public class testDemo {
public static void main(String[] args){
// Cat cat = new Cat();
// System.out.println(cat.name);
// System.out.println(cat.age);
Dog dog = new Dog("wang wang",7);
System.out.println(dog.name);
System.out.println(dog.age);
}
}

成功实例化,并打印
二.不加this
public Dog(String name, int age) {
name = name;
age = age;
}
public class testDemo {
public static void main(String[] args){
// Cat cat = new Cat();
// System.out.println(cat.name);
// System.out.println(cat.age);
Dog dog = new Dog("wang wang",7);
System.out.println(dog.name);
System.out.println(dog.age);
}
}

这个this到底是啥?
public Dog(String name, int age) {
name = name;
age = age;
在这里入过不加this左右两个其实是相等的,赋的是最开始初始化的默认值;
并没有正在的赋值,加上this就有了方向,表示我是当前这个引用,我是来赋值的;
}
Dog类:
package BO_ke2;
public class Dog {
public String name;
public int age;
public Dog(String name, int age) {
this.name = name;
this. age = age;
System.out.println("this是表示当前的引用");
}
}
testDemo类:
package BO_ke2;
public class testDemo {
public static void main(String[] args){
// Cat cat = new Cat();
// System.out.println(cat.name);
// System.out.println(cat.age);
Dog dog = new Dog("wang wang",7);
System.out.println(dog.name);
System.out.println(dog.age);
}
}

3.2this的作用
this访问成员变量
这个很简单
package BO_ke2;
public class Dog {
public String name;
public int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
System.out.println("this是表示当前的引用");
System.out.println("====================");
System.out.println("访问成员变量");
System.out.println("这只狗叫作"+this.name+","+"现在"+this.age+"岁了");
}
}
public class testDemo2 {
public static void main(String[] args){
Dog dog = new Dog("wang wang",7);
}
}

this访问成员方法
方法也是一样的
public class Dog {
public String name;
public int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
System.out.println("this是表示当前的引用");
System.out.println("====================");
System.out.println("访问成员变量");
System.out.println("这只狗叫作"+this.name+","+"现在"+this.age+"岁了");
System.out.println("===================;==");
System.out.println("访问成员方法");
this.wang();
}
public void wang(){
System.out.println(this.name+"正在汪汪叫.......");
}
}

this调用构造方法
注意这个有一点不一样
构造方法是可以有多个的,这个this是可以在构造方法中调用构造方法;
package BO_ke2;
public class Dog {
public String name;
public int age;
public Dog()
{
System.out.println("调用构造方法");
}
public Dog(String name, int age) {
this.name = name;
this.age = age;
// System.out.println("this是表示当前的引用");
// System.out.println("====================");
// System.out.println("访问成员变量");
// System.out.println("这只狗叫作"+this.name+","+"现在"+this.age+"岁了");
// System.out.println("===================;==");
// System.out.println("访问成员方法");
// this.wang();
//
// }
// public void wang(){
// System.out.println(this.name+"正在汪汪叫.......");
// }
// 调用构造方法
this();
}
}


有人在想卡BUG,可不可以两个构造方法甚至多个构造方法,互相调用?
不行,这是个错误,代码会报错
构造方法,并没有强制性,在构造方法中,变量参数搞成不一样的可以避免构造方法,但我们一定要多用,它是很重要的
小结:
①.了解类是什么
②.对象是什么
③.知道基本的初始化
④.知道this是表示当前引用对象
⑤this访问成员变量,成员方法,调用构造方法
四.封装特性
4.1封装概念
不只是JAVA,面向对象的编程都有着三大特性:封装,继承,多态
什么是封装,简单来说就是套壳屏蔽细节
例如一部手机,从外形上看很好看,但它的里面,你不知道,想充电时有专门的接口,有个中扣槽;
4.2访问符
回想一下,我们创建类的时候,不就是封装东西,别人用类里面的方法,只需知道作用就行,其他的统统不考虑;
在之前写代码,都会加上public,这是啥?
这其实就是访问符,public----->公开
表明这是公共的,谁都可以用;
访问限定符共有四个:

有些不懂,还没说,只能讲三个,protected继承才能讲到;
public:表示公开,不同包,同一包里的类都可使用,一般作用于类
private
private:是访问权限最小的包他只能在,自己类中使用,一般作用于成员变量或方法;
public class Student {
private String name;
private int age;
//构造方法
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
看一下测试类

可以看到代码报错了,private将成员属性固定在本类中,其他类没有资格访问
// 初步意识到接口
那我们又想要访问,该咋办?
仔细想一下,我们的手机,它是不是将所有的硬件,芯片都包装起来,我们是不是看不到内部的具体东西,但这并不妨碍我们使用,该打游戏打游戏,该刷视频刷视频;
同理,这个是私有的,别的类无法使用,我们就一些别的方法;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
通过get-set函数来进行访问,这就是一个最简单的接口思想,这个函数是公开的,不是私有,别的类都可以调用;

default
这个访问限定符,是默认限定符,就是你什么都不写,默认为default
class Student{
...........................
}
这就是默认的,同一个包中的不同类可以使用;
先了解,这里不太可能讲全
五.封装扩展之包
5.1包的概念
什么是包?
我们最开始学,就有了导包的概念;做个事例
import java.util.Scanner;
import java.util.Arrays;
包是什么?
包其实就是文件夹,对,就是文件夹,文件夹里面,有各种封装好的类,方法就被封装在这些类中;
第一种:
package bo_ke3;
public class testDemo {
public static void main(String[] args){
java.util.Date date = new java.util.Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
这种就是比较复杂的导包,我们不用,平常我们就是import语句
第二种常用:
package bo_ke3;
import java.util.Arrays;
public class testDemo {
public static void main(String[] args) {
int[] array = new int[]{1, 2, 3, 4, 5};
System.out.println(Arrays.toString(array));
}
}

拓展:我们有一个万能符号可以代替一个类中的所有方法;
import java.util.*;
这样确实方便,不用写出方法,但如果是涉及多个包里的多个类,就容易产生歧义,不同的方法在不同包中,它们的方法名可以相同;
其实我们在来看导包,本质上就是导的包的的路径
以下常用的包:
1. java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
2. java.lang.reflect:java 反射编程包;
3. java.net:进行网络编程开发包。
4. java.sql:进行数据库开发的支持包。
5. java.util:是java提供的工具程序包。(集合类等) 非常重要
6. java.io:I/O编程开发包。
六.static静态
这个我们之前是见过的;
public static void main(){
}
这就是一个静态方法;
静态是存储在静态方法当中,如果在类里写静态方法或静态成员,那他是在类里的,可以用类来引用,也可以用类的实例化;
6.1在谈学生类
Studentl类
public class Student {
// 加修饰限定默认权限为default
public int age;
public String name;
public float score;
public String classNum;
public Student(int age, String name, String classNum, float score) {
this.age = age;
this.name = name;
this.classNum = classNum;
this.score = score;
}
}
测试类:
public class test1 {
public static void main(String[] args)
{
Student student1 = new Student(18,"li si","1班",77.1F);
Student student2 = new Student(17,"xiao wang","1班",66F);
}
}
可以看到我们实例化了两个引用,student1,student2
观察一下这两个学生对象有一个共同就是班级一样;
那我们就可以把这个放到静态区
public class test1 {
public static void main(String[] args)
{
Student student1 = new Student(18,"li si","1班",77.1F);
System.out.println(student1.name);
System.out.println("===================");
Student student2 = new Student(17,"xiao wang","1班",66F);
System.out.println(student2.name);
System.out.println("这是静态");
System.out.println(Student.classNum);
}
}

可以看到是类的引用;
静态可以通过实例化引用吗?
可以,但不推荐,它本身就是属于类的,最好用类引用;
差不多知道就行,还有很多在继承多态会用到;
七.代码块
代码块的主要作用是用来初始化的
普通代码块
public void test(){
{
//静态代码写在方法里面的
this.name = "li si";
......... }
}
静态代码块
static{
}
演示一下
static{
this.name = "li si";
........
}
实例代码块/构造代码块
{
}
注意:不要和普通代码块混淆了,普通代码块是在方法里面的,只有掉用方法的时候才会用到;
其他的比如:静态,实例,构造方法在类的实例化的时候就会执行;
执行顺序
public class Student {
// 加修饰限定默认权限为default
public int age;
public String name;
public float score;
public static String classNum;
public void Func()
{
{
System.out.println("这是普通代码块");
}
}
static{
System.out.println("这是静态代码块");
}
{
System.out.println("这是实例化/构造代码块");
}
public Student() {
System.out.println("这是构造方法");
}
}

二.
package bo_ke4;
public class Student {
// 加修饰限定默认权限为default
public int age;
public String name;
public float score;
public static String classNum;
public void Func()
{
{
System.out.println("这是普通代码块");
}
}
public Student() {
System.out.println("这是构造方法");
}
{
System.out.println("这是实例化/构造代码块");
}
static{
System.out.println("这是静态代码块");
}

这有些不好看,我们用图看下

**在类加载的时候,按静态----->实例----->构造这种顺序执行
其中,普通代码块不是自动执行的,它是在方法里面的,需要调用;
静态加载一次**
public class test1 {
public static void main(String[] args)
{
Student student1 = new Student();
System.out.println("=====================");
Student student2 = new Student();
}
}

说一下,其实在这章里面还有一个内部类,在这里面不讲;
关注我,下期:继承与多态
🦀🦀
更多推荐




所有评论(0)