这部分的内容主要是有关Java中 成员变量与局部变量的区别、形式参数的问题、匿名对象和封装的概念与使用。
成员变量和局部变量的区别
1、在类中定义的位置不同:
成员变量:类中,但是定义在方法外。
局部变量:定义在方法类中。
2、在内存中的位置不同:
成员变量:定义在堆中。
局部变量:定义在栈中。
3、生命周期不同:
成员变量:随着对象的创建而存在,随着对象的结束而结束。
局部变量:随着方法的调用而存在,随着方法的结束而结束。
4、初始化值不同:
成员变量:有默认的初始化值,比如int给的是0,String类型给的是null
局部变量:没有系统给它初始化值,必须在定义的时候给它赋值,才能使用。
注意:
1、方法与方法之间里面的局部变量不能互相调用。
2、局部变量可以和成员变量一样,在方法中使用的时候,采用就近原则。
举例:
class BianLiang {
String name;
int age;
public void show(int n) {
// int n1;
int n1 = 20;
String name = "祥哥";
System.out.println(name);
System.out.println(n1);
}
}
public class BianLiangDemo1 {
public static void main(String[] args) {
BianLiang b1 = new BianLiang();
b1.show(2);
//访问成员变量
System.out.println(b1.name);
}
}
//祥哥
//20
//null
形式参数的问题
在调用方法时,括号里面的参数有两种类型,一种是基本数据类型,一种是引用数据类型。
基本数据类型:形式参数的改变不会影响到实际参数。
引用数据类型:形式参数的改变会直接影响到实际参数。
举例:
//形式参数是引用数据类型
class Student1{
public void speak(){
System.out.println("会说话");
}
}
class StudentTest1{ //想在这个类中的方法里面调用Student类中的speak方法
//如果看到一个方法的形式参数是一个类的类型,说明它是一个引用数据类型
//这里需要的就是该类的对象
//调用时,把main方法中的student的地址传到这里,这里的形参就被传值位实际参数的new Student()
public void function(Student1 s){
s.speak();
}
}
//形式是基本数据类型
class Demo{
public int sum(int a,int b){
return a+b;
}
}
public class StudentDemo {
//想使用StudentTest中的function方法,就需要一个Student类型的参数,这时,就需要继续创建一个Student对象
public static void main(String[] args) {
Student1 stu = new Student1();
StudentTest1 stutest = new StudentTest1();
stutest.function(stu);
Demo demo = new Demo();
int result = demo.sum(1,2);
System.out.println(result);
}
}
//会说话
//3
匿名类
匿名对象:就是没有名字的对象。
匿名对象的使用场景:
1、调用方法的时候,仅仅调用一次的时候,调用多次的时候,不适合。
为什么会存在匿名对象?
因为匿名调用完毕之后,由于栈内存中没有引用指向它,那么调用完毕之后就是垃圾,可以被垃圾回收器回收。
2、匿名对象可以作为实际参数进行传递。
举例:
class Phone1{
public void call(){
System.out.println("手机可以打电话。");
}
}
class Phone1Demo {
public void function(Phone1 p) {
p.call();
}
}
public class AnonymousDemo {
public static void main(String[] args) {
//创建一个Phone1对象
Phone1 p = new Phone1();
p.call();
//创建一个Phone1Demo对象
Phone1Demo p1 = new Phone1Demo();
p1.function(p);
System.out.println("******************使用匿名类进行改进***********************");
new Phone1().call();
new Phone1Demo().function(p);
}
}
//手机可以打电话。
//手机可以打电话。
//******************使用匿名类进行改进***********************
//手机可以打电话。
//手机可以打电话。
封装
关于封装的来源,请大家认真仔细的理解下面这段话:
在一开始,我们尝试着定义一个学生类,学生类里有成员变量:name、age,有成员方法:show()方法
但我们在使用的时候发现了一些问题,我们在给成员变量赋值的时候,可以赋值一些非法的数据,比如,年龄age我们赋值1000,在逻辑上也是合理的,但在我们的认知是非法的。
比如这样:
class Student2{
//定义成员变量
//年龄
int age ;
//姓名
String name;
public void show(){
System.out.println("年龄是:"+age);
System.out.println("姓名是:"+name);
}
}
public class StudentDemo2 {
public static void main(String[] args) {
Student2 stu2 = new Student2();
stu2.age = 1000;
stu2.name = "祥哥";
stu2.show();
}
}
//年龄是:1000
//姓名是:祥哥
你可以看到,年龄被赋值为了1000,在逻辑上没有任何问题,但在认知中是有问题的。
我们就需要做出改变。我们应该在赋值之前,做一次数据校验,也就是堆数据进行一次判断,这时候我们就要考虑,在哪定义比较合适呢,StudentDemo2类是一个测试类,一般情况下,测试类里只能创建对象,调用方法或者是访问成员变量。
所以我们的判断应该定义在Student2中。
但我们在定义成员变量的时候不能加上数据判断,因为数据判断的时候,加的是一些逻辑语句,逻辑语句应该定义在方法中,所以,我们最终添加判断的时候,应该是在Student2提供的一个方法中来做数据校验。
举例:
class Student2{
//定义成员变量
//年龄
int age ;
//姓名
String name;
public void setAge(int a ){
if(a<0 || a>=200){
System.out.println("赋值的年龄有问题");
}else{
age = a;
}
}
public void show(){
System.out.println("年龄是:"+age);
System.out.println("姓名是:"+name);
}
}
public class StudentDemo2 {
public static void main(String[] args) {
Student2 stu2 = new Student2();
stu2.setAge(200);
stu2.age = 1000; //这一行如果注释掉,结果是:赋值的年龄有问题 年龄是:0 姓名是:祥哥
stu2.name = "祥哥";
stu2.show();
}
}
//赋值的年龄有问题
//年龄是:1000
//姓名是:祥哥
可以看到,我们虽然加入了一个方法进行校验,但我们偏偏不调用那个方法来进行赋值,但我们最终还是赋值成功了,这就说明我们给出的方法不起作用,这时,我们就必须使用给出的方法来进行赋值,而不能直接调用成员变量赋值。
怎么去强制要求不能直接使用成员变量呢?
针对这种情况,Java中提供了一个关键字:private
private:私有的,可以修饰成员变量和成员方法。
注意:被private修饰的成员变量或者是成员方法,只能在本类中访问
这就是:封装。
封装:其实就是指隐藏对象的属性和相关实现细节,仅仅对外提供公共访问的方式。
举例:
class Student2{
//定义成员变量
//年龄
private int age ;
//姓名
String name;
public void setAge(int a ){
if(a<0 || a>=200){
System.out.println("赋值的年龄有问题");
}else{
age = a;
}
}
public void show(){
System.out.println("年龄是:"+age);
System.out.println("姓名是:"+name);
}
}
public class StudentDemo2 {
public static void main(String[] args) {
Student2 stu2 = new Student2();
stu2.setAge(21);
// stu2.age = 1000; //这时,这一行直接报错,因为age被定义为私有属性,不能被直接访问
stu2.name = "祥哥";
stu2.show();
}
}
//年龄是:21
//姓名是:祥哥
对private的使用
1、对成员变量用private进行修饰
2、提供对应的getXxx()和setXxx()方法
举例:
class Teacher{
private int age;
private String name;
public void setAge(int n){
age = n;
}
public int getAge(){
return age;
}
public void setName(String n){
name = n;
}
public String getName(){
return name;
}
}
public class PrivateDemo {
public static void main(String[] args) {
Teacher t = new Teacher();
t.setAge(21);
int age = t.getAge();
t.setName("祥哥");
String name = t.getName();
System.out.println(name+"******"+age);
}
}
//祥哥******21
private:
是一个权限修饰符
可以修饰成员变量和成员方法
被修饰的成员变量或者是成员方法只能在本类中使用
举例:
class Demo2{
private int num = 10;
public void show(){
System.out.println(num);
}
private void function(){
System.out.println("这是一个在Demo2中的方法");
}
public void function2(){
function();
}
}
public class PrivateDemo2 {
public static void main(String[] args) {
Demo2 demo2 = new Demo2();
demo2.show();
demo2.function2();
}
}
//10
//这是一个在Demo2中的方法
举例:
class Phone{
private int price;
private String brand;
private String color;
public void setPrice(int p){
price = p;
}
public int getPrice(){
return price;
}
public void setBrand(String b){
brand = b;
}
public String getBrand(){
return brand;
}
public void setColor(String c){
color = c;
}
public String getColor(){
return color;
}
}
public class PrivateDemo3{
public static void main(String[] args) {
Phone p = new Phone();
p.setPrice(800);
p.setBrand("祥哥的牌子");
p.setColor("黄色");
int price = p.getPrice();
System.out.println(price+"******"+p.getColor()+"******"+p.getBrand());
}
}
//800******黄色******祥哥的牌子
This关键字
变量的使用原则:就近原则
直接通过类名.成员变量是报错的
如果这个Student3这个对象存在,它就代表着一个学生对象
但是,谁可以代表这个当前类的对象呢
Java中提供了一个关键字:this
举例:
class Student3{
//姓名
private String name;
//年龄
private int age;
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
//对name成员变量进行赋值
public void setName(String name){
//变量的使用原则:就近原则
//直接通过类名.成员变量是报错的,目前还没有说过类似的用法,所以这个是有问题的
//如果这个Student3这个对象存在,他就代表着一个学生对象
//但是,谁可以代表这个当前类的对象呢?
//Java就提供了一个关键字:this
this.name = name;
}
public String getName(){
return name;
}
}
public class ThisDemo {
public static void main(String[] args) {
Student3 stu3 = new Student3();
stu3.setAge(21);
stu3.setName("祥哥");
int age = stu3.getAge();
String name = stu3.getName();
System.out.println(name+"**********"+age);
}
}
//祥哥**********21
感谢阅读,我是啊帅和和,一位大数据专业即将大四学生,祝你快乐。