【Java SE】类和对象
1.面向对象
1.1什么是面向对象?
面向对象(Object Oriented)是软件开发方法,一种编程范式。面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。 面向对象是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。【百度百科】
1.2 面向对象与面向过程
- 传统洗衣服过程 传统的方式:注重的是洗衣服的过程,少了一个环节可能都不行。 而且不同衣服洗的方式,时间长度,拧干方式都不同,处理起来就比较麻烦。如果将来要洗鞋子,那就是另一种放方式。按照该种方式来写代码,将来扩展或者维护起来会比较麻烦。
- 现代洗衣服过程 以面向对象方式来进行处理,就不关注洗衣服的过程,具体洗衣机是怎么来洗衣服,如何来甩干的,用户不用去关心,只需要将衣服放进洗衣机,导入洗衣粉,启动开关即可,通过对象之间的交互来完成的
2.类的定义和使用
2.1 类的定义格式
在java中定义类时需要用到class关键字,具体语法如下
// 创建类
class ClassName{
field;
// 字段(属性) 或者 成员变量
method;
// 行为 或者 成员方法
}
- 类名注意采用大驼峰定义
- 方法名/变量名一般为加粗样式
- 成员前写法统一为public,后面会详细解释
- 此处写的方法不带 static 关键字. 后面会详细解释
举例如下:
举一反三:我们来定义一个书的类:
3.类的实例化
3.1 什么是实例化
定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义了一个新的类型,比如上述的:PetDog类和Student类。它们都是类(一种新定义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。 用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。
- new 关键字用于创建一个对象的实例.
- 使用 . 来访问对象中的属性和方法.
- 同一个类可以创建对个实例.
3.2类和对象的说明
- 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.
- 类是一种自定义的类型,可以用来定义变量.
- 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
- 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间
4.this引用
4.1什么是this引用
我们先来看一个代码:
- 当形参名不小心与成员变量名相同时,我们可以看到结果如下:
这是因为当形参名和成员变量名相同时,编译器会认为这是同一个值,**C语言中规定局部变量优先,只是形参自己给自己赋值了,根本没有赋值到成员变量中。**所以打印的值为默认的值。0
- . 三个对象都在调用setDate和printDate函数,但是这两个函数中没有任何有关对象的说明,setDate和printDate函数如何知道打印的是那个对象的数据呢?
4.2this引用的特性
- this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
- this只能在"成员方法"中使用
- 在"成员方法"中,this只能引用当前对象,不能再引用其他对象
- this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收
5.对象的构造及初始化
5.1构造方法
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。
构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间。
构造方法的特点:
- 名字必须与类名相同
- 没有返回值类型,设置为void也不行
- 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每
- 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)
- 如果用户没有定义任何的构造方法,编译器会生成一份默认的构造方法,生成的默认构造方法一定是无参的。 注意:一旦用户定义,编译器则不再生成。
- 构造方法中,可以通过this调用其他构造方法来简化代码
注意: this(…)必须是构造方法中第一条语句 不能形成环
5.2 就地初始化
在声明成员变量时,就直接给出了初始值。
代码编译完成后,编译器会将所有给成员初始化的这些语句添加到各个构造函数中
6.封装
6.1封装的概念
面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性。 封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互
6.2访问限定符
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符:
比如: public:可以理解为一个人的外貌特征,谁都可以看得到 default: 对于自己家族中(同一个包中)不是什么秘密,对于其他人来说就是隐私了 private:只有自己知道,其他人都不知道 【注意】: default权限指:什么都不写时的默认权限 访问权限除了可以限定类中成员的可见性,也可以控制类的可见性 这些访问修饰限定符,只是在权限上进行了限制
6.3封装扩展——包
6.3.1包的概念
在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类收集在一起成为一组,称为软件包。有点类似于目录。 在Java中也引入了包,包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式,比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。
6.3.2 导入包中的类
如果需要使用 java.util 中的其他类, 可以使用 import java.util.* 比如前面我们学习数组时使用 Arrays.toString(arr); 时要导入import java.util.Arrays; 建议显式的指定要导入的类名. 否则还是容易出现冲突的情况.比如:
正确的写法:
可以使用import static导入包中静态的方法和字段。(了解即可,不建议使用)
6.3.3 自定义包
【基本规则】
- 在文件的最上方加上一个 package 语句指定该代码在哪个包中.
- 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式
- 包名要和代码路径相匹配.
- 如果一个类没有 package 语句, 则该类被放到一个默认包中.
6.3.4 常见的包
- java.lang:系统常用基础类(String、Object),此包从JDK1.1后自动导入。
- java.lang.reflect:java 反射编程包;
- java.net:进行网络编程开发包。
- java.sql:进行数据库开发的支持包。
- java.util:是java提供的工具程序包。(集合类等) 非常重要
- java.io:I/O编程开发包。
7.static成员
static修饰的成员变量,称为静态成员变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的。
比如说在一个班中,同学1和同学2等都是在一个班的,虽然他们的个人信息不同 但是属于同一个班,对于班级,我们就可以设置为static成员,其位置在方法区。
【静态成员变量特性】
- 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
- 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
- 类变量存储在方法区当中
- 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)
那static属性应该如何访问呢? Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。
【静态方法特性】
- 不属于某个具体的对象,是类方法
- 可以通过对象调用,也可以通过**类名.静态方法名(…)**方式调用,更推荐使用后者
- 不能在静态方法中访问任何非静态成员变量
- 静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用。
7.1static成员变量初始化
静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化。
- 就地初始化 就地初始化指的是:在定义时直接给出初始值
- .静态代码块初始化
8.代码块
8.1 代码块概念以及分类
使用 { } 定义的一段代码称为代码块。 普通代码块 构造块 静态块
8.2 普通代码块
普通代码块:定义在方法中的代码块
8.3 构造代码块
构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量。
8.4 静态代码块
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
- 静态代码块不管生成多少个对象,其只会执行一次
- 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
- 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
- 实例代码块只有在创建对象时才会执行
当三种代码块一起出现时,静态代码块会最先运行,且只运行一次,与对象是否创建无关。
先运行静态代码块再运行实例代码块,再构造方法。静态代码块会最先运行,且只运行一次
9.内部类
**当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构最好使用内部类。**在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。
- 定义在class 类名{ } 花括号外部的,即使是在一个文件里,都不能称为内部类
- 内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件
9.1 内部类的分类
内部类分为:
- 实例内部类
- 静态内部类
- 局部内部类
- 匿名内部类
9.1.1实例内部类
即未被static修饰的成员内部类。
1.如何获取 实例内部类的对象
内部类可以无限套,但是不建议!!!
2.实例内部类当中不能有静态的成员变量,非要定义,那么只能是被static final 修饰的
成员函数的执行需要外部类对象的引用,static属于类的成员,类加载的时候static就可能会被执行
原因如下: 内部类在类中定义相当于一个成员,必须要先有成员,才能有内部类,而static的执行优先于内部类,因此会发生报错。
why? 加上final之后就说明是常量是10,在编译之后就确定了。 final是常量的意思。
常量是在程序编译的时候确定的,一旦初始化,就不能进行修改了。
3.在实例内部类当中,如何访问外部类当中,相同的成员变量? 如果想在内部类中使用外部类的data1,则修改代码: 类名.this.外部类成员 即可
【注意事项】
- 外部类中的任何成员都可以在实例内部类方法中直接访问
- 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
- 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名 称.this.同名成员 来访问
- 实例内部类对象必须在先有外部类对象前提下才能创建
- 实例内部类的非静态方法中包含了一个指向外部类对象的引用
- 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
9.1.2静态内部类
被static修饰的内部成员类称为静态内部类。
- 如何获取静态内部类对象?
OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2();
- 静态内部类当中,不能访问外部类的非静态成员。外部类的非静态成员,需要通过外部类的对象的引用才能访问。 非要访问:
OuterClass2 outerClass = new OuterClass2();
System.out.println(outerClass.data1);
9.1.3局部内部类
定义在外部类的方法体或者{ } 中,该种内部类只能在其定义的位置使用 【注意事项】
- 局部内部类只能在所定义的方法体内部使用
- 不能被public、static等修饰符修饰
- 编译器也有自己独立的字节码文件,命名格式:外部类名字$内部类名字.class
10.对象的打印
生成一个这样的:toString
帮助你检查重新的的对不对,即注解。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: 【Java SE】类和对象
本文地址: https://pptw.com/jishu/6622.html