Java基础-07(01).总结private,this,封装,static,成员方法变量,局部变量匿名对象

时间:2022-05-04
本文章向大家介绍Java基础-07(01).总结private,this,封装,static,成员方法变量,局部变量匿名对象,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1:成员变量和局部变量的区别(理解)

(1)在类中的位置不同

成员变量:类中方法外

局部变量:方法定义中或者方法声明上

(2)在内存中的位置不同

成员变量:在堆中

局部变量:在栈中

(3)生命周期不同(成员的创建与销毁时间)

成员变量:随着对象的创建而存在,随着对象的消失而消失

局部变量:随着方法的调用而存在,随着方法的调用完毕而消失

(4)初始化值不同

成员变量:有默认值

局部变量:没有默认值,必须定义,赋值,然后才能使用

(5)使用范围

成员变量:在整个类中都可以访问

局部变量:只能在当前方法访问

(6)变量的使用原则:就近原则

如果在方法中找到,使用局部变量

如果在类中方法外找到,使用成员变量

如果在类中没有找到,报错

/*
 成员变量和局部变量的区别?
 A:在类中的位置不同
 成员变量:在类中方法外
 局部变量:在方法定义中或者方法声明上
 B:在内存中的位置不同
 成员变量:在堆内存
 局部变量:在栈内存
 C:生命周期不同
 成员变量:随着对象的创建而存在,随着对象的消失而消失
 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
 D:初始化值不同
 成员变量:有默认初始化值
 局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
 注意事项:
 局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
*/
class Varialbe {
 //成员变量
 //int num = 10;
 int num; //0
 public void show() {
 //int num2 = 20; //局部变量
 //可能尚未初始化变量num2
 //int num2; //没有默认值
 int num2 = 20;
 System.out.println(num2);
 //int num = 100;
 System.out.println(num);
 }
}
class VariableDemo {
 public static void main(String[] args) {
 Varialbe v = new Varialbe();
 System.out.println(v.num); //访问成员变量
 v.show(); 
 }
}

2:类作为形式参数的问题(理解)

(1)如果你看到一个方法需要的参数是一个类名,就应该知道这里实际需要的是一个具体的对象。

/*
 形式参数的问题:
 基本类型:形式参数的改变不影响实际参数
 引用类型:形式参数的改变直接影响实际参数
*/
//形式参数是基本类型
class Demo {
 public int sum(int a,int b) {
 return a + b;
 }
}
//形式参数是引用类型
class Student {
 public void show() {
 System.out.println("我爱学习");
 }
}
class StudentDemo {
 //如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
 public void method(Student s) { //调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();
 s.show();
 }
}
class ArgsTest {
 public static void main(String[] args) {
 //形式参数是基本类型的调用
 Demo d = new Demo();
 int result = d.sum(10,20);
 System.out.println("result:"+result);
 System.out.println("--------------");
 //形式参数是引用类型的调用
 //需求:我要调用StudentDemo类中的method()方法
 StudentDemo sd = new StudentDemo();
 //创建学生对象
 Student s = new Student();
 sd.method(s); //把s的地址给到了这里
 }
}

3:匿名对象(理解)

(1)没有名字的对象

(2)应用场景

A:调用方法,仅仅只调用一次的时候。

b:作为调用方法的实际参数使用

匿名对象:就是没有名字的对象。

匿名对象的应用场景:

A:调用方法,仅仅只调用一次的时候。

注意:调用多次的时候,不适合。

那么,这种匿名调用有什么好处吗?

有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。

B:匿名对象可以作为实际参数传递

*/
class Student {
 public void show() {
 System.out.println("我爱学习");
 }
}
class StudentDemo {
 public void method(Student s) {
 s.show();
 }
}
class NoNameDemo {
 public static void main(String[] args) {
 //带名字的调用
 Student s = new Student();
 s.show();
 s.show();
 System.out.println("--------------");
 //匿名对象
 //new Student();
 //匿名对象调用方法
 new Student().show();
 new Student().show(); //这里其实是重新创建了一个新的对象
 System.out.println("--------------");
 //匿名对象作为实际参数传递
 StudentDemo sd = new StudentDemo();
 //Student ss = new Student();
 //sd.method(ss); //这里的s是一个实际参数
 //匿名对象
 sd.method(new Student());
 //在来一个
 new StudentDemo().method(new Student());
  }
}

4:封装(理解)

(1)隐藏实现细节,提供公共的访问方式

(2)好处:

A:隐藏实现细节,提供公共的访问方式

B:提高代码的复用性

C:提高代码的安全性

(3)设计原则

把不想让外界知道的实现细节给隐藏起来,提供公共的访问方式

(4)private是封装的一种体现。

封装:类,方法,private修饰成员变量

/*
 定义一个学生类:
 成员变量:name,age
 成员方法:show()方法
 我们在使用这个案例的过程中,发现了一个问题:
 通过对象去给成员变量赋值,可以赋值一些非法的数据。
 这是不合理的。
 应该是这个样子的:在赋值之前,先对数据进行判断。
 判断到底在哪里做比较合适呢?
 StudentDemo类是一个测试类,测试类一般只创建对象,调用方法。 
 所以,这个判断应该定义在Student类中。
 而我们在成员变量的位置可不可以进行数据判断呢?
 是不可以的,因为做数据校验,必须要依靠一些逻辑语句。
 逻辑语句是应该定义在方法中的,所以,我们最终决定在Student类中提供一个方法
 来对数据进行校验。
 按照我们前面的分析,我们给出了一个方法进行校验。
 但是呢,它偏偏不调用方法来赋值,还是直接赋值了,
 这样我们的方法就没有起到作用。
 我就应该要求你必须使用我的方法,而不能直接调用成员变量赋值。
 怎么去强制要求不能直接使用成员变量呢?
 针对这种情况,Java就提供了一个关键字 private
 private:私有的。可以修饰成员变量和成员方法。
 注意:被private修饰的成员只能在本类中访问。
 其实我讲到现在讲解的是一个封装的思想。
 封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
*/
class Student {
 //姓名
 String name;
 //年龄
 private int age;
 //写一个方法对数据进行校验
 /*
 返回值类型:void
 参数列表:int a
 */
 public void setAge(int a) {
 if(a < 0 || age > 120) {
 System.out.println("你给的年龄有问题");
 }else {
 age = a;
 }
 }
 //show()方法,显示所有成员变量值
 public void show() {
 System.out.println("姓名:"+name);
 System.out.println("年龄:"+age);
 }
}
class StudentDemo {
 public static void main(String[] args) {
 //创建学生对象
 Student s = new Student();
 s.show();
 System.out.println("--------------");
 //给成员变量赋值
 s.name = "林青霞";
 //s.age = 27;
 s.setAge(27);
 s.show();
 System.out.println("--------------");
 //给age赋值
 //s.age = -27; //这个数据是不合理的
 //通过方法给值
 s.setAge(-27);
 s.show();
 System.out.println("--------------");
 }
}

5:private关键字(掌握)

(1)私有的意义,可以修饰成员变量和成员方法

(2)特点:

被private修饰的后的成员只能在本类中被访问

(3)private的应用:

以后再写一个类的时候:

把所有的成员变量给private了

提供对应的getXxx()/setXxx()方法

/*
 private:
 是一个权限修饰符
 可以修饰成员变量和成员方法
 被其修饰的成员只能在本类中被访问
*/
class Demo {
 //int num = 10;
 //用private修饰
 private int num = 10;
 public void show() {
 System.out.println(num);
 }
 private void method() {
 System.out.println("method");
 }
 public void function() {
 method();
 }
}
class PrivateDemo {
 public static void main(String[] args) {
 Demo d = new Demo();
 //不能方法私有的成员变量
 //System.out.println(d.num);
 d.show();
 //不能访问私有的成员方法
 //d.method();
 d.function();
 }
}
/*  应用:
 封装和private的应用:
 A:把成员变量用private修饰
 B:提高对应的getXxx()和setXxx()方法
*/
//定义学生类
class Student {
 //姓名
 private String name;
 //年龄
 private int age;
 //姓名获取值
 public String getName() {
 return name;
 }
 //姓名设置值
 public void setName(String n) {
 name = n;
 }
 //年龄获取值
 public int getAge() {
 return age;
 }
 //年龄赋值
 public void setAge(int a) {
 age = a;
 }
}
//测试类
class StudentTest {
 public static void main(String[] args) {
 //创建学生对象
 Student s = new Student();
 //使用成员变量
 //错误:被私有修饰了,外界不能直接访问了
 //System.out.println(s.name+"---"+s.age);
 System.out.println(s.getName()+"---"+s.getAge());
 //给成员变量赋值
 //s.name = "林青霞";
 //s.age = 27;
 //通过方法给赋值
 s.setName("林青霞");
 s.setAge(27);
 System.out.println(s.getName()+"---"+s.getAge());
 }
}

6:this关键字(掌握)

(1)代表当前类的引用对象

记住:哪个对象调用方法,该方法内部的this就代表那个对象

(2)this的应用场景:

A:解决了局部变量隐藏成员变量的问题

B:其实this还有其他的应用,明天讲解。

/*
 作业:请把手机类写成一个标准类,然后创建对象测试功能。
 手机类:
 成员变量:
 品牌:String brand;
 价格:int price;
 颜色:String color;
 成员方法:
 针对每一个成员变量给出对应的getXxx()/setXxx()方法。
 最后定义测试:
 创建一个对象,先通过getXxx()方法输出成员变量的值。这一次的结果是:null---0---null
 然后通过setXxx()方法给成员变量赋值。再次输出结果。这一次的结果是:三星---2999---土豪金
*/
class Phone {
 //品牌
 private String brand;
 //价格
 private int price;
 //颜色
 private String color;
 //getXxx()和setXxx()方法
 public String getBrand() {
 return brand;
 }
 public void setBrand(String brand) {
 this.brand = brand;
 }
 public int getPrice() {
 return price;
 }
 public void setPrice(int price) {
 this.price = price;
 }
 public String getColor() {
 return color;
 }
 public void setColor(String color) {
 this.color = color;
 }
}
class PhoneTest {
 public static void main(String[] args) {
 //创建手机对象
 Phone p = new Phone();
 //直接输出默认值
 System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+p.getColor());
 //给成员变量赋值
 p.setBrand("三星");
 p.setPrice(2999);
 p.setColor("土豪金");
 //再次输出
 System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+p.getColor());
 }
}
/*
 我们曾经曰:起名字要做到见名知意。
 this:是当前类的对象引用。简单的记,它就代表当前类的一个对象。
 注意:谁调用这个方法,在该方法内部的this就代表谁。
 this的场景:
 解决局部变量隐藏成员变量
*/
//定义学生类
class Student {
 //姓名
 private String name;
 //年龄
 private int age;
 //姓名获取值
 public String getName() {
 return name;
 }
 //姓名设置值
 public void setName(String name) { //name = "林青霞";
 //name = name; //变量的使用规则:就近原则
 //这里是类名,目前还没有说过类似的用法,所以这个是有问题的
 //这里的调用只能通过对象名
 //这个对象如果存在,它应该代表的是Student的一个对象。
 //那么,谁能够代表当前类的对象呢? java就提供了一个关键字 this
 //Student.name = name;
 this.name = name;
 }
 //年龄获取值
 public int getAge() {
 return age;
 }
 //年龄赋值
 public void setAge(int age) {
 this.age = age;
 }
}
//测试类
class StudentTest {
 public static void main(String[] args) {
 //创建学生对象
 Student s = new Student();
 //给成员变量赋值
 s.setName("林青霞");
 s.setAge(27);
 //获取数据
 System.out.println(s.getName()+"---"+s.getAge());
 }
}
/*
 标准的代码改进版
 this:哪个对象调用那个方法,this就代表那个对象
*/
class Student {
 private String name;
 private int age;
 public String getName() {
 return name; //这里其实是隐含了this
 }
 public void setName(String name) {
 this.name = name;
 }
 public int getAge() {
 return age;
 }
 public void setAge(int age) {
 this.age = age;
 }
}
class StudentTest2 {
 public static void main(String[] args) {
 //创建一个对象
 Student s1 = new Student();
 s1.setName("林青霞");
 s1.setAge(27);
 System.out.println(s1.getName()+"---"+s1.getAge());
 //创建第二个对象
 Student s2 = new Student();
 s2.setName("刘意");
 s2.setAge(30);
 System.out.println(s2.getName()+"---"+s2.getAge());
 }
}

7:构造方法(掌握)

(1)作用:用于对对象的数据进行初始化

(2)格式:

A:方法名和类名相同

B:没有返回值类型,连void都不能有

C:没有返回值

思考题:构造方法中可不可以有return语句呢?

可以。而是我们写成这个样子就OK了:return;

其实,在任何的void类型的方法的最后你都可以写上:return;

(3)构造方法的注意事项

A:如果我们没写构造方法,系统将提供一个默认的无参构造方法

B:如果我们给出了构造方法,系统将不再提供默认构造方法

如果这个时候,我们要使用无参构造方法,就必须自己给出。

推荐:永远手动自己给出无参构造方法。

(4)给成员变量赋值的方式

A:setXxx()

B:带参构造方法

(5)标准案例

 class Student {
 private String name;
 private int age;
 public Student(){}
 public Student(String name,int age) {
 this.name = name;
 this.age = 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;
 }
 }
 测试:
 class StudentDemo {
 public static void main(String[] args) {
 //方式1
 Student s1 = new Student();
 s1.setName("林青霞");
 s1.setAge(27);
 System.out.println(s1.getName()+"---"+s1.getAge());
 //方式2
 Student s2 = new Student("刘意",30);
 System.out.println(s2.getName()+"---"+s2.getAge());
 }
 }
/*
 我们一直在使用构造方法,但是,我们确没有定义构造方法,用的是哪里来的呢?
 构造方法的注意事项:
 A:如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
 B:如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
 注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
 给成员变量赋值有两种方式:
 A:setXxx()
 B:构造方法
*/
class Student {
 private String name;
 private int age;
 public Student() {
 //System.out.println("我给了,你还给不");
 System.out.println("这是无参构造方法");
 }
 //构造方法的重载格式
 public Student(String name) {
 System.out.println("这是带一个String类型的构造方法");
 this.name = name;
 }
 public Student(int age) {
 System.out.println("这是带一个int类型的构造方法");
 this.age = age;
 }
 public Student(String name,int age) {
 System.out.println("这是一个带多个参数的构造方法");
 this.name = name;
 this.age = age;
 }
 public void show() {
 System.out.println(name+"---"+age);
 }
}
class ConstructDemo2 {
 public static void main(String[] args) {
 //创建对象
 Student s = new Student();
 s.show();
 System.out.println("-------------");
 //创建对象2
 Student s2 = new Student("林青霞");
 s2.show();
 System.out.println("-------------");
 //创建对象3
 Student s3 = new Student(27);
 s3.show();
 System.out.println("-------------");
 //创建对象4
 Student s4 = new Student("林青霞",27);
 s4.show();
 }
}
/*
 类的组成:成员变量,成员方法
 今天我们又加入了一个新的成员:构造方法。
 以后再提类的组成:
 成员变量
 构造方法
 成员方法
 根据返回值:
 void类型
 非void类型
 形式参数:
 空参方法
 非空参方法
*/
class Student {
 public String getString() {
 return "helloworld";
 }
 public void show() {
 System.out.println("show");
 }
 public void method(String name) {
 System.out.println(name);
 }
 public String function(String s1,String s2) {
 return s1+s2;
 }
}
class StudentDemo {
 public static void main(String[] args) {
 //创建对象
 Student s = new Student();
 //调用无参无返回值方法
 s.show();
 //调用无参有返回值方法
 String result = s.getString();
 System.out.println(result);
 //调用带参无返回值的方法
 s.method("林青霞");
 //调用带参带返回值的方法
 String result2 = s.function("hello","world");
 System.out.println(result2);
 }
}
/*
 一个标准代码的最终版。
 学生类:
 成员变量:
 name,age
 构造方法:
 无参,带两个参
 成员方法:
 getXxx()/setXxx()
 show():输出该类的所有成员变量值
 给成员变量赋值:
 A:setXxx()方法
 B:构造方法
 输出成员变量值的方式:
 A:通过getXxx()分别获取然后拼接
 B:通过调用show()方法搞定
*/
class Student {
 //姓名
 private String name;
 //年龄
 private int age;
 //构造方法
 public Student() {
 }
 public Student(String name,int age) {
 this.name = name;
 this.age = 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 void show() {
 System.out.println(name+"---"+age);
 }
}
//测试类
class StudentTest {
 public static void main(String[] args) {
 //方式1给成员变量赋值
 //无参构造+setXxx()
 Student s1 = new Student();
 s1.setName("林青霞");
 s1.setAge(27);
 //输出值
 System.out.println(s1.getName()+"---"+s1.getAge());
 s1.show();
 System.out.println("----------------------------");
 //方式2给成员变量赋值
 Student s2 = new Student("刘意",30);
 System.out.println(s2.getName()+"---"+s2.getAge());
 s2.show();
 }
}

8:代码:Student s = new Student();做了哪些事情?(理解)

(1)把Student.class文件加载到内存

(2)在栈内存为s开辟空间

(3)在堆内存为学生对象申请空间

(4)给学生的成员变量进行默认初始化。null,0

(5)给学生的成员变量进行显示初始化。林青霞,27

(6)通过构造方法给成员变量进行初始化。刘意,30

(7)对象构造完毕,把地址赋值给s变量