哪怕犯错,也不能什么都不做。
主页:趋早–Step
专栏:JAVASE
gitte:https://gitee.com/good-thg
接上部分,我们继续来学习JAVAEE类和对象。
引言:
这篇文章接上一篇,后半部分,结束类和对象
目录
- 一、封装
- 1、封装的概念
- 2、访问限定符
- 注意:
- (1)我们在需要生成代码的地方点击鼠标右键,然后选择下面的Geneate
- (2)然后就会出现下面的界面
- (3)这时候我们选择图片中的选项
- (4)点进来的界面是这样的
- (5)我们按住Ctrl 或者 Shift 键,用鼠标点击需要生成的方法
- (6)最后点击下面的OK,他就会自动生成了。
- 3、包
- (1)概念
- (2)导入包中的类
- (3)自定义包
- <1> 选择src并且右键点击
- <2> 选择new
- <3> 选择Package并且点击
- <4> 输入包的名称,这里我输入的是demo2(可以自己定义名字),然后回车,就创建好了一个包。我们来说一下创建包的基本原则:
- 1.在文件的最上方加上一个 package 语句指定该代码在哪个包中
- 2.包名需要尽量指定成唯一的名字,通常会用公司的域名的颠倒形式
- 3.报名要和代码路径想匹配
- 4.如果一个类没有package语句,则该类被放到一个默认包中。
- (4)包的访问权限控制举例
- 二、static成员
- 1、再谈学生类
- 2、static修饰成员变量
- 3、static修饰成员方法
- 4、static成员变量初始化
- (1)就地初始化
- (2)静态代码块初始化
- 三、代码块
- 1、代码块概念以及分类
- 2、普通代码块
- 3、构造代码块
- 4、静态代码块
- 拓展:
- 四、内部类
- 1、内部类的分类
- 2、实例内部类
- 3、静态内部类
- 4、局部内部类
- 5、匿名内部类
- 五、对象的打印
一、封装
1、封装的概念
面向对象程序三大特性:封装、继承、多态。
而类和对象截断,主要研究的就是封装特性。何为封装呢?简单来说就是套壳屏蔽细节。
比如我们使用的手机,我们可以给手机充电,可以开关机,可以调节手机音量的高低,可以看到手机内的应用,但是我们看不到手机内部的构造,这就是厂商将内部细节封装起来了,我们无法看到。
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
2、访问限定符
JAVA中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用,JAVA提供了四种访问操作符:
当然,我们也是通过代码来学习封装的,我们看下面这个代码:
class Person{
public String name;
public int age;
public void show(){
System.out.println("姓名:" + name + " 年龄: " + age);
}
}
public class Text {
public static void main(String[] args) {
Person person = new Person();
person.name = "Tom";
person.age = 12;
person.show();
}
}
运行结果如下:
上面的代码我们已经很熟悉了吧!但是,上面这个代码不够安全,容易被修改,所以,这时候封装的意义就体现出来了,我们将代码进行修改:
很明显,这个代码已经有错了,因为private修饰了属性和方法,private的权限是同一个包中的同一类,上面代码中不在同一个类,所以就会出错,再来看下面代码:
我们将它放在同一个类中就不会报错了,我们运行试试:
这就是运行结果了。
这时候,我们想,如果我们非要在类外面访问,该怎么办呢?
这也是有方法的,我们继续:
class Person{
private String name;
private int age;
public void show(){
System.out.println("姓名:" + name + " 年龄: " + age);
}
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;
}
}
public class Text {
public static void main(String[] args) {
Person person = new Person();
//person.name = "Tom";
//person.age = 12;
person.setName("Sam");
person.setAge(15);
System.out.println(person.getName());
System.out.println(person.getAge());
}
}
看代码,我们运行一下试试:
这个代码就叫做封装。我们可以提供公开的方法进行访问,这就相当于我们的手机充电口,我们可以给手机充电,但是我们不知道他是实现的细节。
注意:
这时候,我们说一个小技巧,我们看到那么多方法,需要一个一个字母敲出来可真的太浪费时间了,为了提供我们的效率,我们就用快捷方式,我们的IDEA功能非常的强大,可以自动帮助我们生成,如何生成呢?让我来告诉你:
我们先把那些方法删除,现在的代码是这样:
然后就来生成吧!
(1)我们在需要生成代码的地方点击鼠标右键,然后选择下面的Geneate
(2)然后就会出现下面的界面
(3)这时候我们选择图片中的选项
(4)点进来的界面是这样的
(5)我们按住Ctrl 或者 Shift 键,用鼠标点击需要生成的方法
(6)最后点击下面的OK,他就会自动生成了。
我们看结果:
这就是我们编译器自动生成的方法,是不是和好用的,当然,我在这里写的比较繁琐,我们自己使用的时候完全不会这么麻烦的,同时,我们再告诉大家一个快捷键 Alt + Insert,他也能帮助我们生成上面的方法,至于他怎么使用,大家自己尝试一下就知道了,需要我们自己动手哦。
3、包
(1)概念
在面向对象体系中,提出了一个软件包的概念,即:为了更好的管理类,把多个类手机在一起成为一组。比如我们的一个文件夹,文件夹中的内容就是类,可以帮助我们更好的管理类。
在JAVA中,包是对类、接口等封装机制的体现,是一种类对接口等的很好的组织方式,比如一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的嘞,只要处在不同的包中即可。
(2)导入包中的类
我们使用import语句来导入包
我们看下面的代码:
这就是导入了包,运行结果如下:
(3)自定义包
我们如何自定义包呢?下面就来介绍一下:
<1> 选择src并且右键点击
<2> 选择new
<3> 选择Package并且点击
<4> 输入包的名称,这里我输入的是demo2(可以自己定义名字),然后回车,就创建好了一个包。我们来说一下创建包的基本原则:
1.在文件的最上方加上一个 package 语句指定该代码在哪个包中
2.包名需要尽量指定成唯一的名字,通常会用公司的域名的颠倒形式
3.报名要和代码路径想匹配
4.如果一个类没有package语句,则该类被放到一个默认包中。
(4)包的访问权限控制举例
我们在demo2中定义一个Date类:
然后我们在demo1中的Text中进行访问:
这样,我们就可以访问不同包中的类了。
二、static成员
1、再谈学生类
public class Student {
public String name;
public int age;
public String gender;
public double score;
public Student(String name, int age, String gender, double score) {
this.name = name;
this.age = age;
this.gender = gender;
this.score = score;
}
public void print(){
System.out.println(this.name + "今年" + this.age + "岁了,他是一个" +
this.gender + "生,这次的考试成绩是" + this.score + "分");
}
public static void main(String[] args) {
Student student1 = new Student("Tom",12,"男",66);
Student student2 = new Student("XiaoHong",13,"女",76);
Student student3 = new Student("Sam",12,"男",86);
student1.print();
student2.print();
student3.print();
}
}
运行结果如下:
好的,后面的操作我们都是在这个代码上提出问题并且在这个代码上修修改改。
这时候,我们有了第一个问题,假如他们三个人都在同一个班中,那么我们有必要都存一份吗?很明显是没有必要的,所以,这个时候我们的static就出马了。
在JAVA中,被static修饰的成员,称之为静态变量,也可以称为类成员,其不属于某个具体的对象,是所有对象所共享的。
2、static修饰成员变量
static修饰的成员变量,称为静态变量,静态成员变量最大的特性:不属于某个具体的对象,是所有对象所共享的。
静态成员变量特性:
1.不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中。
2.既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
3.类变量存储在方法区中
4.生命周期伴随类的一生。(随类的加载而加载,随类的卸载而销毁)
运行结果如下:
上面的代码,我们是已经给班级赋值了,如果不赋值会是怎样呢?
我们看代码:
剩下的不改变,运行一下:
这里称为了null,至于为什么?咱们可以看看上一篇文章就懂啦!
我们也可以在类外赋值,如何赋值呢?看代码:
3、static修饰成员方法
成员方法同样也是使用类名进行访问的,在JAVA中,被static修饰的成员方法称为静态成员方法,是类的方法,不是某个对象所特有的。静态成员一般是通过静态方法来访问的。
静态方法特性:
1.不属于某个具体的对象,是类方法
2.可以通过对象调用,也可以通过类名调用,更推荐使用类名调用
3.不能在静态方法中访问任何非静态成员变量
4.静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法调用时候无法传递this引用。
我们用代码说明一下上面的特性3和4
这就是本部分的内容啦,但是还没有结束,咱们的思维导图还没有整理完哦。
4、static成员变量初始化
(1)就地初始化
就地初始化就是在定义时就直接给出初始值
(2)静态代码块初始化
还记得这张图吗?就让我们继续学习吧!
三、代码块
1、代码块概念以及分类
使用{}定义的一段代码称为代码块,根据代码块定义的位置以及关键字,又可分为以下四种:
1.普通代码块
2.构造块
3.静态块
4.同步代码块
2、普通代码块
定义在方法中的代码块
运行结果如下:
3、构造代码块
定义在类中的代码块,也叫实例代码块。构造代码块一般用于初始化实例成员变量。
4、静态代码块
使用static定义的代码块称为静态代码块,一般用于初始化静态成员变量。
拓展:
在这里我们拓展一个点,我们先看代码:
public class Student {
public String name;
public int age;
public static String classes;
public Student(){
System.out.println("不带参数的构造方法");
}
public Student(String name, int age) {
System.out.println("带两个参数的构造方法");
this.name = name;
this.age = age;
}
{
System.out.println("这是实例代码块/构造块");
}
// 类加载的时候就会执行
static {
System.out.println("这是静态代码块");
}
public void show(){
System.out.println(this.name + "今年" + this.age + "岁了");
}
public static void main(String[] args) {
Student student = new Student();
}
}
我们运行一下看结果:
我们的静态代码块在类加载的时候就会执行了,我们把main方法改成下面这样并且运行试试:
这就证明了我们上面的答案。
这个时候,我们再看下面的代码:
我们发现再次实例化的时候,静态代码块就没有再执行了。
这就是因为静态的只会执行一次
注意:
1.静态代码块不管生成多少个对象,其只会执行一次
2.静态成员变量是类的属性,因此是在JVM加载嘞时开辟空间并且初始化的
3.如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行
4.实例代码块只有在创建对象时才会执行
四、内部类
当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。
在JAVA中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类,内部类也是封装的一种体现。
1、内部类的分类
实例内部类
静态内部类
局部内部类
匿名内部类
2、实例内部类
class Outer{
public int data1;
int data2;
public static int data3;
public void test(){
System.out.println("Outer --> test()");
}
// 实例内部类 --> 未被static修饰
class Inner{
public int data4;
int data5;
public void func(){
System.out.println("Inner --> func()");
}
}
}
public class Test {
}
我们已经写好了上面的代码,我们就慢慢来理解实例内部类吧!
如何获取内部类的对象
我们可以把内部类看做一个实例成员,使用外部类的对象来调用
使用上面的两种方法都是可以的。
注意:
1.外部类中的任何成员变量都可以在内部类方法中直接访问
2.实例内部类所处的位置与外部类成员位置相同,因此也受public,private等访问限定符的约束
3.在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员来访问
4.实例内部类对象必须在先有外部类对象的前提下才能创建
5.实例内部类的非静态方法中包含了一个指向外部类对象的引用
6.外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象
3、静态内部类
class Outer{
public int data1 = 1;
int data2 = 2;
public static int data3 = 3;
public void test(){
System.out.println("Outer-->test()");
}
static class Inner{
public int data4 = 4;
int data5 = 5;
public static int data6 = 6;
public void func(){
System.out.println("Inner-->func()");
}
}
}
public class Test {
public static void main(String[] args) {
}
}
如何获取静态内部类对象
注意:
1.在静态内部类中只能访问外部类中的静态成员
当然,如果我们非要访问也是有办法的:
2.创建静态内部类对象时,不需要先创建外部类对象。
4、局部内部类
定义在外部类的方法体或者{}中,该中内部类只能在其定义的位置使用,使用很少
public class Test {
public void func(){
// 局部内部类
class Inner{
}
}
public static void main(String[] args) {
}
}
注意:
1.局部内部类只能在所定义的方法体内部使用
2.不能被public,static等修饰
3.编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
4.几乎不会使用
5、匿名内部类
class Person{
public String name;
public int age;
}
public class Test {
public static void main(String[] args) {
// 匿名对象 只能使用一次
new Person();
System.out.println(new Person().name);
System.out.println(new Person().age);
// 匿名内部类
new Person(){
};
}
}
五、对象的打印
class Person{
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void print(){
System.out.println(this.name + "今年" + this.age + "岁了");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person("Tom",12);
person.print();
}
}
运行结果如下:
我们可以看到,我们每次打印的时候需要调用print方法,当字段很多的时候,我们写print方法的时候会显得函麻烦,这时候我们就需要更简单的方法了。在我们JAVA中就有这样的方法,我们先看下面的代码:
我们看到红色方框中的是一堆看不懂的东西(它当然是有意义的,我们这里不说他是什么意思),我们想要把它变成打印里面的对象该怎么办呢?
这时候就需要用到我们所说的toString方法了
看代码:
class Person{
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void print(){
System.out.println(this.name + "今年" + this.age + "岁了");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person("Tom",12);
person.print();
System.out.println(person);
}
}
运行结果如下:
我们同样是有快捷键来生成toString方法的,我们看下面的步骤
1.右键 --> Generate
2.找到toString()点击并选择就可以可以生成啦
或者使用Alt + Insert ,剩下的步骤是完全一样的。
我们JAVASE之类和对象部分就全部学习完啦,但是我们还需要继续努力,继续加油!!!