承接上篇文章的讲解,这一篇文章将带你完整了解类和对象。
面向对象程序三大特性:封装、继承、多态。而类和对象阶段,主要研究的就是封装特性
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互
封装就是套壳屏蔽细节,打我们生活中的常识来说,电脑的设计,电脑的核心设计以及主板电路,cpu的设计都被外壳包裹的紧紧的,把这些重要的内部细节隐藏了起来,仅仅给我们提供了一些数据接口,鼠标接口和键盘接口。
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用,在Java里有四种访问限定符。
3.protected:受保护的,这个修饰限定符在继承之后会讲到
4.default:在同一个包中可以随意访问,默认权限,包访问权限
注意:一般情况下成员变量设置为private,成员方法设置为public
6.3.1 包的概念
为了更好的管理类,把多个类收集在一起成为一组,称为软件包。
包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式,比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。
在我们生活中我们可以把包理解为文件夹,然后每个文件夹都更好的帮我们对事物的分类,比如歌曲文件夹,资料文件夹,游戏文件夹等等。
6.3.2 导入包中的类
在我们前面其实就以及提到过导入包中的类了,在数组里的Arrays,会在前面导入一个import java.util.,这个最后的表示导入util包中所有的类,在我们实例化对象的时候也可以导入包(java.util.Date date = new java.util.Date();),不过这样相对麻烦,更建议类似于头文件那里导入包。
在这里值得我们注意的是util包里和sql包里都有Date,这时候就冲突了,就必须要明确规定导入哪个包。
还有一种静态导入
当导入的包加了static和Math之后,在代码区的Math就都可以省略了,写起来很方便,但是不推荐使用,容易使我们弄混淆,
6.3.3 自定义包
基本规则:
在文件的最上方加上一个 package 语句指定该代码在哪个包中.
包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.baidu. www).
包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
如果一个类没有 package 语句, 则该类被放到一个默认包中.
操作步骤:
这个的作用是声明包的路径
那我们如何让他们包里面的内容相互引用呢?
如图所示各种情况,都在bit包里面的时候,怎么彼此引用
6.3.5 常见的包
每个学生都有自己特有的名字、性别,年龄,学分绩点等成员信息,这些信息就是对不同学生来进行描述的。
之前在Student类中定义的成员变量,每个对象中都会包含一份(称之为实例变量),因为需要使用这些信息来描述具体的学生。而现在要表示学生上课的教室,这个教室的属性并不需要每个学生对象中都存储一份,而是需要让所有的学生来共享。在Java中,被static修饰的成员,称之为静态成员,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。
static修饰的成员变量,称为静态成员变量。
静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的。
静态成员变量特性:
不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
类变量存储在方法区当中
生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)
静态成员变量并没有存储到某个具体的对象中
Java中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。
静态方法特性:
总结注意:
1. 静态的成员变量和成员方法都不依赖于对象,因为他们是类变量。非静态的成员变量是依赖于对象的
2. 普通的成员方法中是可以使用静态成员变量的
3. 静态的成员方法中,不能访问非静态的成员(成员变量,成员方法)
注意:静态成员变量一般不会放在构造方法中来初始化,构造方法中初始化的是与对象相关的实例属性
静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化。
使用 {} 定义的一段代码称为代码块。
根据代码块定义的位置以及关键字,又可分为以下四种:
构造块:定义在类中的代码块(不加修饰符),构造代码块一般用于初始化实例成员变量。
当我们实例化一个学生时,会优先执行实例代码块(与代码顺序无关),所以我们在实例代码块内赋值会被构造方法赋值给覆盖,最后的结果就是构造方法给的值。
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
优先级最高,最先执行。
注意事项:
如果定义了多个静态代码块,那么打印的结果只和他们的前后顺序有关。
概念:一个类的内部定义一个类,定义的类叫内部类
为什么实例内部类当中不能定义静态的成员变量,如果要定义,必须是编译的时候确定的值(必须是static final)
实例内部类当中,如果有成员变量和外部类的成员变量重名了,怎么办?
优先使用自己的!!那我们如何拿到外部类的变量呢?用外部类名.this.
从这里我们可以意识到实例内部类当中,不仅包含了自己的this,而且包含了外部类的this。所以在内部类当中不可以定义静态的方法!
总结:
9.1.2.静态内部类:
被static修饰的内部成员类称为静态内部类。
我们在外部类中定义三个数据,在静态内部类中定义三个数据,然后在静态内部类方法当中访问每个数据:
从上图我们可以得知,在静态内部类中,只能访问外部类的静态的成员。那么要访问外部非静态成员我们该如何访问?
在这里只需提供一个外部类对象即可,来实例化外部类对象。
注意:
定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少,此处简单了解下语法格式。
局限性:只能在该方法体内部使用,其他位置都不能用
注意:
对象的打印就是我们前面提及的IDEA中简洁方法,鼠标右键点击空白生成Generate再点击ToString生成你想要打印的成员变量,具体模板可以参考我上一篇类和对象(上)的最后的文段。
到此类和对象就完工了,经过两篇文章的详细描述,你get到了其中的奥妙了吗?