javaSE:类和对象

 

目录

1. 面向对象的初步认知

1.1 什么是面向对象 

2. 类定义和使用  

2.1 简单认识类 和类的定义格式

 3. 类的注意事项

4. 类的实例化

4.1 什么是实例化 

 4.2 类实例化后的内存关系 

  4.3 类和对象的说明

5. this引用

 5.1为什么要有this

5.2什么是this引用

5.3 this引用的特性

 6. 对象的构造及初始化

6.1 如何初始化对象 

 6.2 构造方法

5.2.1 概念

 6.2.2 特性

6.3 默认初始化 

7.封装

7.1 封装的概念 

7.2访问修饰限定符(了解)

7.3private实现封装 

 目前对于成员的赋值:

7.3 封装扩展之包 

 7.3.1 包的概念

7.3.2 导入包中的类

7.3.3 自定义包 

7.3.4 包的访问权限控制举例

7.3.5 常见的包 


1. 面向对象的初步认知

1.1 什么是面向对象 

面向过程:按照每个步骤依次进行

我们以洗碗为例

在洗碗的过程中我们需要把每个事情都过一遍

 面向对象:完成某件事的时候,只需要和对象之间进行交互,那么这个事情就可以完成。

面向对象方式来进行处理,就不关注洗碗的过程 ,具体洗碗机是怎么洗碗的,如何来甩干的,用户不用去关心,只需要将碗放进洗碗机,导入洗洁精,启动开关即可, 通过对象之间的交互来完成的

2. 类定义和使用  

2.1 简单认识类 和类的定义格式

类是用来对一个实体 ( 对象 ) 来进行描述的 ,主要描述该实体 ( 对象 ) 具有哪些属性 ( 外观尺寸等 ) ,哪些功能 ( 用来干啥 ) ,描述完成后计算机就可以识别了。
类:
1,定义一个类【类型:int byte char ......】【自定义类型】
语法格式:
// 创建类
class ClassName{ //className:类名
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法 
}
class为定义类的关键字,ClassName为类的名字,{}中为类的主体。
类中包含的内容称为类的成员。
属性主要是用来描述类的,称之为类的成员属性或者类成员变量。
方法主要说明类具有哪些功能,称为类的成员方法
简单定义格式:
class Student {
    //成员变量:成员变量要定义在类的内部,方法的外部
    String name;
    int age;
    //方法-》行为
    public void eat(){
        System.out.println(name+"正在吃饭");
    }
    public void sleep(){
        System.out.println(name+"正在睡觉");
    }
    public void study(){
        System.out.println(name+"正在学习");
    }
}

注意事项:

  • 类名注意采用大驼峰定义
  • 成员前写法统一为public.
  • 此处写的方法不带 static 关键字.
  • 成员变量要定义在类的内部,方法的外部

 3. 类的注意事项

1.一般一个文件当中只定义一个类

error:

不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改

注意事项:

  1. 一般一个文件当中只定义一个类
  2. main方法所在的类一般要使用public修饰
  3. public修饰的类必须要和文件名相同
  4. 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改

4. 类的实例化

4.1 什么是实例化 

定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义了一个新的类型,比如上的:PetDog类和Student类。它们都是类(一种新定 义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。

由类产生对象的过程---->类的实例化,在java中采用new关键字,配合类名来实例化对象

class Student {
    //成员变量
    String name;
    int age;
    //方法-》行为
    public void eat(){
        System.out.println(name+"正在吃饭");
    }
    public void sleep(){
        System.out.println(name+"正在睡觉");
    }
    public void study(){
        System.out.println(name+"正在学习");
    }
}
public class Test {
    public static void main(String[] args) {
                           //通过new实例化了一个对象
        Student student1 = new Student();
        student1.name="李华";
        student1.age=18;
        student1.eat();
        student1.sleep();
        student1.study();


        Student student2 = new Student();
        student2.name="阿文";
        student2.age=19;
        student2.eat();
        student2.sleep();
        student2.study();
    }
}

在这里我们是通过“ . ”来访问对象中的属性和方法

 但是当我们的成员变量没有初始化数值的时候是什么呢?

class Student {
    //成员变量
    String name;
    int age;
    //方法-》行为
    public void eat(){
        System.out.println(name+"正在吃饭");
    }
    public void sleep(){
        System.out.println(name+"正在睡觉");
    }
    public void study(){
        System.out.println(name+"正在学习");
    }
}
public class Test {
    public static void main(String[] args) {
        Student student=new Student();
        System.out.println(student.name);
        System.out.println(student.age);
        
    }
}

 

 我们可以知道当成员变量么有初始化时:

1,引用数据类型->null

2,基本数据类型(int byte long short...)->0

3,boolean->false

4,char->'\u0000'

注意事项:

  • new 关键字用于创建一个对象的实例.
  • 使用 ‘ . ’ 来访问对象中的属性和方法.
  • 同一个类可以创建多个实例.

 4.2 类实例化后的内存关系 

当我们实例化一个对象后,只会把类中的成员/属性实例化到对象中,而方法并不会在对象中存储,当调用某个对象的方法时,还是会在栈上创建函数栈帧去进行计算 

注意:

  1. 创建的对象只会存储成员/属性到对象中,方法不会出现在对象中
  2. 当调用对象的方法时,还是会从栈中创建栈帧去计算

  4.3 类和对象的说明

1. 类只是 一个 模型 一样的东西,用来对一个实体进行描述,限定了类有哪些成员 .
2. 类是一种自定义的类型 ,可以用来定义变量 .
3. 一个类可以实例化出多个对象, 实例化出的对象 占用实际的物理空间,存储类成员变量
4. 做个比方。 类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图 ,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空

 

5. this引用

 5.1为什么要有this

先看一个日期类的例子:

class Date {
    public int year;
    public int month;
    public int day;

    public void setDate(int y, int m, int d) {
        year = y;
        month = m;
        day = d;
    }

    public void printDate() {
        System.out.println(year + "/" + month + "/" + day);
    }
}

public class TestDemo {
    public static void main(String[] args) {
        // 构造三个日期类型的对象 d1 d2 d3
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();
        // 对d1,d2,d3的日期设置
        d1.setDate(2022,4,15);
        d2.setDate(2022,4,16);
        d3.setDate(2022,4,17);
        // 打印日期中的内容
        d1.printDate();
        d2.printDate();
        d3.printDate();
    }
}

在这里有一个问题形参名不小心与成员变量名相同:
假如我将类中的setDay方法改成如下,那方法知道那个是成员变量那个是形参名吗,到最后打印就会出问题如果要区分那就需要this引用了

此时方法中的局部变量优先

public void setDay(int year, int month, int day){//局部变量优先
	year = year;
	month = month;
	day = day;
}

如果要区分那就需要this引用了

public void setDay(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }

5.2什么是this引用

 this引用:this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问

所以我建议大家在这种调用时都加上"this",能用则用。

5.3 this引用的特性

1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
2. this只能在"成员方法"中使用
3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象  

 6. 对象的构造及初始化

6.1 如何初始化对象 

通过前面知识点的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。 

public static void main(String[] args) {
int a;
System.out.println(a);
}
// Error:(26, 28) java: 可能尚未初始化变量a

要让上述代码通过编译,非常简单,只需在正式使用a之前,给a设置一个初始值即可。如果是对象:

public static void main(String[] args) {
Date d = new Date();
d.printDate();
d.setDate(2021,6,9);
d.printDate();
}
// 代码可以正常通过编译

需要调用之前写的SetDate方法才可以将具体的日期设置到对象中。通过上述例子发现两个问题:
1. 每次对象创建好后调用SetDate方法设置具体日期,比较麻烦,那对象该如何初始化?


2. 局部变量必须要初始化才能使用,为什么字段声明之后没有给值依然可以使用?

因为在上方我们说过 :

 我们可以知道当成员变量么有初始化时:

1,引用数据类型->null

2,基本数据类型(int byte long short...)->0

3,boolean->false

4,char->'\u0000'

 6.2 构造方法

5.2.1 概念

 构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次

public class Date {
	public int year;
	public int month;
	public int day;
	// 构造方法:
	// 名字与类名相同,没有返回值类型,设置为void也不行
	// 一般情况下使用public修饰
	// 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
	public Date(int year, int month, int day){
		this.year = year;
		this.month = month;
		this.day = day;
		System.out.println("Date(int,int,int)方法被调用了");
	}
	public void printDate(){
		System.out.println(year + "-" + month + "-" + day);
	}
	public static void main(String[] args) {
		// 此处创建了一个Date类型的对象,并没有显式调用构造方法
		Date d = new Date(2021,6,9); // 输出Date(int,int,int)方法被调用了
		d.printDate(); // 2021-6-9
	}
}

 6.2.2 特性

1. 名字必须与类名相同


2. 没有返回值类型,设置为void也不行


3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)


4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法) 

public class Date {
	public int year;
	public int month;
	public int day;
	// 无参构造方法
	public Date(){
	this.year = 1900;
	this.month = 1;
	this.day = 1;
	}
	// 带有三个参数的构造方法
	public Date(int year, int month, int day) {
		this.year = year;
		this.month = month;
		this.day = day;
	}//构成重载
	public void printDate(){
		System.out.println(year + "-" + month + "-" + day);
	}

    public static void main(String[] args) {
    Date d = new Date();
    d.printDate();
    }
}

5. 如果用户没有显式定义,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。

public class Date {
	public int year;
	public int month;
	public int day;
	public void printDate(){
		System.out.println(year + "-" + month + "-" + day);
	}
}
	public static void main(String[] args) {
		Date d = new Date();
		d.printDate();
	}

上述Date类中,没有定义任何构造方法,编译器会默认生成一个不带参数的构造方法。
注意:一旦用户定义,编译器则不再生成。
所以要想好要不要定义构造方法

public class Date {
	public int year;
	public int month;
	public int day;
	public Date(int year, int month, int day) {
	this.year = year;
	this.month = month;
	this.day = day;
	}
	public void printDate(){
		System.out.println(year + "-" + month + "-" + day);
	}
	public static void main(String[] args) {
	// 如果编译器会生成,则生成的构造方法一定是无参的
	// 则此处创建对象是可以通过编译的
	// 但实际情况是:编译期报错
	Date d = new Date();
	d.printDate();
}
/*
Error:(26, 18) java: 无法将类 extend01.Date中的构造器 Date应用到给定类型;
需要: int,int,int
找到: 没有参数
原因: 实际参数列表和形式参数列表长度不同
*/

对于构造方法存在简易的构造方法生成

6. 构造方法中,可以通过this调用其他构造方法来简化代码

public class Date {
	public int year;
	public int month;
	public int day;
	// 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复
	// 此处可以在无参构造方法中通过this调用带有三个参数的构造方法
	// 但是this(1900,1,1);必须是构造方法中第一条语句
	public Date(){
		//System.out.println(year); 注释取消掉,编译会失败
		this(2022, 5, 11);
		//this.year = 1900;
		//this.month = 1;
		this.day = 1;
	}
	// 带有三个参数的构造方法
	public Date(int year, int month, int day) {
		this.year = year;
		this.month = month;
		this.day = day;
	}
	public void printDate() {
		System.out.println(year + "-" + month + "-" + day);
	}

    public static void main(String[] args) {
        Date date=new Date();
		date.printDate();
    }
}

在这里面的this是调用另一个带有3个参数的构造方法


1.this()必须在构造方法中调用


2.this()必须在构造方法中的第一行


3.this()不能在本构造方法中调用自己形成环,这样会死循环

 

7.this.func;调用当前对象的成员方法

public Date(int year, int month, int day) {
		
		this.year = year;
		this.month = month;
		this.day = day;
		this.printDate();
	}

6.3 默认初始化 

public class Date {
  public int year;
  public int month;
  public int day;
  public Date(int year, int month, int day) {
  // 成员变量在定义时,并没有给初始值, 为什么就可以使用呢?
    System.out.println(this.year);
    System.out.println(this.month);
    System.out.println(this.day);
  }
  public static void main(String[] args) {
    // 此处a没有初始化,编译时报错:
    // Error:(24, 28) java: 可能尚未初始化变量a
    // int a;
    // System.out.println(a);
    Date d = new Date(2021,6,9);
  }
}

关于这个问题我们已经在6.1的第二个问题稍微讲解了一下,需要的话可以返回上方看一下

要搞清楚这个过程,就需要知道 new 关键字背后所发生的一些事情:

Date d = new Date(2022,5,2);

在程序层面只是简单的一条语句,在JVM层面需要做好多事情,下面简单介绍下:

    1.检测对象对应的类是否加载了,如果没有加载则加载
    2.为对象分配内存空间
    3.处理并发安全问题
    比如:多个线程同时申请对象,JVM要保证给对象分配的空间不冲突。
    4.初始化所分配的空间
    即:对象空间被申请好之后,对象中包含的成员已经设置好了初始值,比如:

数据类型默认值      
byte0
char'\u0000'
short0
int0
long0L
booleanfalse
float0.0f
double0.0
referencenull

5.设置对象头信息

6.调用构造方法,给对象中各个成员赋值

7.封装

7.1 封装的概念 

 面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性。何为封装呢?简单来说
就是套壳屏蔽细节

不想让类外看到我具体的实现细节,所以,我通过技术手段将这些细节进行封装,对这个类的细节 进行隐藏,提供一些公开的接口,让你来进行交互

比如:对于电脑这样一个复杂的设备,提供给用户的就只是:开关机、通过键盘输入,显示器,USB插孔等,让用
户来和计算机进行交互,完成日常事务。但实际上:电脑真正工作的却是CPU、显卡、内存等一些硬件元件

 封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互

7.2访问修饰限定符(了解)

Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认
知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符 

 比如:
public:可以理解为一个人的外貌特征,谁都可以看得到


default: 对于自己家族中(同一个包中)不是什么秘密,对于其他人来说就是隐私了


private:只有自己知道,其他人都不知道:只能在当前类中访问
【说明】
protected主要是用在继承中,继承部分详细介绍


default权限指:什么都不写时的默认权限


访问权限除了可以限定类中成员的可见性,也可以控制类的可见性

7.3private实现封装 

我新建了一个类->TestDemo,在public修饰时,哪哪都可以用,我在TestDemo中也可以运用

我能在另外一个类中再访问,其原因是都为public修饰

但是当我将year改为private类型的后

 此时year只能在当前类里面访问:也就是说被private修饰后只能在类中使用被修饰的成员变量或者方法,就是说在类外不能实现其封装的属性了

  • 被 public 修饰的成员变量或者成员方法, 可以直接被类的调用者使用.
  • 被 private 修饰的成员变量或者成员方法, 不能被类的调用者使用.

如果 想在private的情况下来使TestDemo实现year的功能

我们要为这个year提供一个公开的接口

当我们对三个对象都进行private修饰的时候

我们可以使用快捷键来代替手敲代码来得到setmonth和setday以及getmonth和getday:

 后面的操作步骤同上

 目前对于成员的赋值:

 1.定义字段的时候,同时初始化->就地初始化

public class Date {
  public int year = 1900;
  public int month = 1;
  public int day = 1;
    public Date(){
    }
      public Date(int year, int month, int day) {
    }
    public static void main(String[] args) {
      Date d1 = new Date(2021,6,9);
      Date d2 = new Date();
    }
}

2.不初始化

public class Date {
  public int year;
  public int month;
  public int day;
  public Date(int year, int month, int day) {
  // 成员变量在定义时,并没有给初始值, 为什么就可以使用呢?
    System.out.println(this.year);
    System.out.println(this.month);
    System.out.println(this.day);
  }
  public static void main(String[] args) {
    // 此处a没有初始化,编译时报错:
    // Error:(24, 28) java: 可能尚未初始化变量a
    // int a;
    // System.out.println(a);
    Date d = new Date(2021,6,9);
  }
}

3.在类外,通过对象的引用直接赋值

student.name="李华";
student.age=18;

4.通过构造方法初始化

public class Date {
	public int year;
	public int month;
	public int day;
	// 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复
	// 此处可以在无参构造方法中通过this调用带有三个参数的构造方法
	// 但是this(1900,1,1);必须是构造方法中第一条语句
	public Date(){
		//System.out.println(year); 注释取消掉,编译会失败
		this(2022, 5, 11);
		//this.year = 1900;
		//this.month = 1;
		this.day = 1;
	}
	// 带有三个参数的构造方法
	public Date(int year, int month, int day) {
		this.year = year;
		this.month = month;
		this.day = day;
	}
	public void printDate() {
		System.out.println(year + "-" + month + "-" + day);
	}

    public static void main(String[] args) {
        Date date=new Date();
		date.printDate();
    }
}

5.提供提供get和set来实现

7.3 封装扩展之包 

 7.3.1 包的概念

在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件
。有点类似于目录。比如:为了更好的管理电脑中的歌曲,一种好的方式就是将相同属性的歌曲放在相同文件
下,也可以对某个文件夹下的音乐进行更详细的分类 

 相当于通过定义一些java文件夹把一些Java文件归类到一些文件夹当中

7.3.2 导入包中的类

当我们去创建一个类后发现

多出来了一行:

package www.wwwsuper.com;

这个是用来声明当前Java文件 是在哪个包低下

 在我们平时的编程中我们也运用到过包

 通过import来导包

 

我们有两种方式来实现

但是我们可以发现Date有两种类型的包,出现冲突

我们只能通过

 在前方定义来区分!

在我们重复使用静态方法时我们可以使用import static导入包中静态的方法和字段。

注意事项: import 和 C++ 的 #include 差别很大. C++ 必须 #include 来引入其他文件内容, 但是 Java 不需要.import 只是为了写代码的时候更方便. import 更类似于 C++ namespace 和 using

7.3.3 自定义包 

 基本规则
在文件的最上方加上一个 package 语句指定该代码在哪个包中.
    1.包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.bit.demo1 ).
    2.包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
    3.如果一个类没有 package 语句, 则该类被放到一个默认包中.
操作步骤
1. 在 IDEA 中先新建一个包: 右键 src -> 新建 -> 包

操作方法:

 我们可以去文件夹里查看创建了什么:

7.3.4 包的访问权限控制举例

Computer类位于www.bite.demo1包中,TestComputer位置www.bite.demo2包中: 

package www.bite.demo1;

public class Computer {
    private String cpu; // cpu
    private String memory; // 内存
    public String screen; // 屏幕
    String brand; // 品牌
    public Computer(String brand, String cpu, String memory, String screen) {
        this.brand = brand;
        this.cpu = cpu;
        this.memory = memory;
        this.screen = screen;
    }
    public void Boot(){
        System.out.println("开机~~~");
    }
    public void PowerOff(){
        System.out.println("关机~~~");
    }
    public void SurfInternet(){
        System.out.println("上网~~~");
    }
}
package www.bite.demo2;

import www.bite.demo1.Computer;
public class TestComputer {
    public static void main(String[] args) {
        Computer p = new Computer("HW", "i7", "8G", "13*14");
        System.out.println(p.screen);
// System.out.println(p.cpu); // 报错:cup是私有的,不允许被其他类访问
// System.out.println(p.brand); // 报错:brand是default,不允许被其他包中的类访问
    }
}
// 注意:如果去掉Computer类之前的public修饰符,代码也会编译失败

7.3.5 常见的包 

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编程开发包。 

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆腐乾净找方规

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值