提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
随着Java学习的不断深入,本文就介绍了Java进阶的关于变量,this,封装和隐藏的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、变量
1.成员变量
- Java中,变量分为成员变量(类中定义)和局部变量(方法中定义)。
Java中的变量又分为类属性(有static修饰)和实例属性(无static修饰)
成员变量也叫属性。
2.成员变量与局部变量的区别
1.类的位置不同。
成员变量在类中,局部变量在方法里。
2.内存位置不同。
成员变量在堆中,局部变量在栈里。
3.生命周期不同。
成员变量随对象的创建而存在,消失而消失
4.初始值不同。
成员变量有默认值,局部变量无默认值,用前得赋值,要不然报错
3.语法
[<修饰符>] [static][final]<变量类型><变量名>
(1)static:表示一个类的成员变量,也叫静态成员变量
(2)final:表示一个常量
4.代码练习
1.实例成员变量
public class Person {
String country;
String name;
int age;
@Override
public String toString() {
return "Person{" +
"country='" + country + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
toString方法是自动生成的,在idea中按alt+insert然后找到toString()即可
用测试类调用上述代码:
public class Test {
public static void main(String[] args) {
//创建对象1
Person p1 = new Person();
p1.country = "长沙";
p1.name = "张三";
p1.age = 18;
//创建对象2
Person p2 = new Person();
//输出
System.out.println(p1);
System.out.println(p2);
}
}
运行结果如图:
通过结果我们发现测试类中name赋值为张三,age为18,这是实例属性,而对象2中name和age均未赋值,所以两个变量中包含了各自的实例属性
以上就是实例成员变量的使用
2.类成员变量
但是Java中还有一个类成员变量,也被称为静态成员变量,它用static修饰,一个类成员变量由该类的所有实例对象共享,而不是任何一个类实例的变量,在访问类成员变量时,不用先实例化它所在的类,因为类成员变量保存在该类的公共内存区存储单元里,而不是某个对象的内存区域中。
二、this关键字
Java提供一个this关键字,它总是指向调用该方法的对象。
谁在调用该方法,this就代表谁
1.方法中调用方法或成员变量
this关键字最大的作用就是让类中一个方法访问该类中另一个方法或实例成员变量
代码如下(示例):
(1)创建Hero
public class Hero {
//定义jump方法类
public void jump(){
System.out.println("--英雄遇到障碍要跳过去--");
}
public void run(){
System.out.println("--英雄正在奔跑--");
//创建hero对象
Hero hero = new Hero();
System.out.println("hero内存地址为:"+hero.hashCode()+"它要跳起来了");
//调用jump方法
hero.jump();
}
}
(2)创建TestHero类,并调用上述代码的对象
public class TestHero {
public static void main(String[] args) {
//创建英雄对象hero
Hero hero = new Hero();
System.out.println("hero的内存地址为:"+hero.hashCode()+"它将跑起来");
//调用run()方法
hero.run();
}
}
运行结果如图:
由图可以知道,明明我们hero引用的是同一个对象,但是内存地址不同,这是为什么呢?
在上述程序中,我们创建了两个Hero对象,在Hero类中run()方法中创建了一个,在TestHero中又创建了一个对象
这样就有两个问题:
- 在run()方法中调用jump()方法是否一定需要一个Hero对象?
- 是否一定要重新创建一个Hero对象?
很明显第一个问题答案是肯定的,因为没有static修饰的属性或方法都必用对象来调用。
第二个答案是否定的,因为程序调用run()方法时,一定会提供一个Hero对象,这样我们可以直接用这个已经存在的东西,不用重新创建对象
因此,我们通过this关键字可以满足该需求。
public class Hero {
//定义jump方法
public void jump(){
System.out.println("--英雄遇到障碍要跳过去--");
}
public void run(){
System.out.println("--英雄正在奔跑--");
//创建hero对象
Hero hero = new Hero();
System.out.println("hero内存地址为:"+this.hashCode()+"它要跳起来了");
//调用jump方法
this.jump();
}
}
运行结果如图:
内存地址变成一样的了。
由此可知this可以代表任何对象,当this出现在方法里时,代表的对象是不固定的,但类型是确定的,其所代的对象只能是当前类,只有被调用时,它代表的对象才被确定下来,谁调用它,它就代表谁。
2.解决实例变量和局部变量重名问题
<font color=#999AAA >代码如下(示例):
public class Hero {
String name;
//定义jump方法
public void setName(String name;){
name = name; //此处易混淆,可读性差
}
public static void main(String[] args) {
//创建hero对象
Hero hero = new Hero();
hero.setName("精灵");
System.out.println("hero的名字为:"+hero.name);
}
}
运行结果如图:
在上述setName方法中,name=name很明显不清楚你要调用的name是哪一个,我们得改用this方法来区分调用的name变量:
public class Hero {
String name;
//定义jump方法
public void setName(String name){
this.name = name; //"this.变量"表示调用该类的实例变量
}
public static void main(String[] args) {
//创建hero对象
Hero hero = new Hero();
hero.setName("精灵");
System.out.println("hero的名字为:"+hero.name);
}
}
运行结果如图:
成功解决了重名问题。
三、隐藏和封装
1.封装的概念
封装是面对对象的三大特性之一,它是指将对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象的内部信息,而是通过该类所提供的方法实现对内部信息的操作和访问。
封装的目的:
- 隐藏类的实现细节
- 在方法中加入控制逻辑,用来限制对属性不合理的访问。
- 进行数据检查,有利于保证对象信息的完整性。
- 便于修改提供代码的可维护性。
实现良好的封装,要从以下两个方面考虑:
- 隐藏对象的属性和实现细节,不允许外部直接访问。
- 暴露出方法,让方法控制这些对属性进行安全的访问和操作。
总而言之:隐藏该隐藏的、暴露该暴露的
2.代码练习
(1)创建Hero类用来封装信息
public class Hero {
private String name;
private int age;
public void setName(String name){
if(5<=name.length() && name.length()<=16) {
this.name = name;
}else {
System.out.println("名字长度必须在【5-16】");
}
}
public void setAge(int age){
if(1<=age && age<=120) {
this.age = age;
}else {
System.out.println("年龄范围必须在【1-120】");
}
}
@Override
public String toString() {
return "Hero{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
(2)创建HeroTest类
public class TestHero {
public static void main(String[] args) {
//创建hero对象
Hero hero = new Hero();
hero.setName("1234"); //名字不满足5-16之间
System.out.println(hero);
hero.setName("abcde"); //名字满足条件
System.out.println(hero);
hero.setAge(200); //年龄不满足1-120之间
System.out.println(hero);
hero.setAge(18);//年龄满足条件
System.out.println(hero);
}
}
运行结果如图:
通过上述例子,可以发现把类进行合理封装,可以大大提高我们代码的合理性和安全性。
3.使用访问修饰符
private只是Java访问修饰符的一种,按照从小到大的顺序,以下给出Java其他的访问控制符。
访问修饰符 | 同一个类中 | 同一个包中 | 子类中 | 所有类中 |
---|---|---|---|---|
private | ✔ | — | — | — |
default | ✔ | ✔ | — | — |
protected | ✔ | ✔ | ✔ | — |
public | ✔ | ✔ | ✔ | ✔ |
通过上表可知:访问控制符用于控制一个类成员是否被其他类访问。对于局部变量而言,其作用域就是它在的方法,因此不可能被其他类访问,也不能使用访问控制修饰符。
四、static关键字
Java类的运行包括类加载和实例化两个阶段,当一个类被加载到JVM中,静态成员会被初始化,被static修饰成员变量被称为静态成员。
它包括静态代码块、静态属性和静态方法
总结
提示:这里对文章进行总结:
上就是今天要讲的内容,本文仅仅简单介绍了变量和this,等下会继续更新关于封装,包,之类的问题,下次再见。