欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

7. 面向对象 -- 成员与局部变量和封装

程序员文章站 2024-02-18 15:25:04
...

目录

1:成员变量和局部变量的区别(掌握)

2:类作为形式参数的问题?(掌握)

3:匿名对象(掌握)

4:封装(理解)

5:封装和private关键字的应用(掌握)

6:this关键字(掌握)

7:构造方法(掌握)

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

9:面向对象的练习题(掌握)

10:static关键字(掌握)


1:成员变量和局部变量的区别(掌握)

       (1)在类中的位置不同

              成员变量:类中方法外

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

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

              成员变量:在堆中

              局部变量:在栈中

       (3)生命周期不同

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

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

       (4)初始化值不同

              成员变量:有默认值

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

注意事项:

              局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。

2:类作为形式参数的问题?(掌握)

形式参数的问题:

              基本类型:形式参数的改变不影响实际参数

              引用类型:形式参数的改变直接影响实际参数      

如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。

 

class Demo {
    publicint getSum(int a,int b) {
           return a + b;
    }
}
class Test {
    publicstatic void main(String[] args) {
           Demo d = new Demo();
           System.out.println(d.getSum(10,20));
    }
}

 

讲解的时候,先说我们去吃饭,调用服务员的记菜功能,然后服务员调用厨师的做菜功能。

完毕后,厨师调用服务员的端菜功能,最后,我们吃就OK了。

 

class Student {
    publicvoid show() {
           System.out.println(“show”);
    }
}
class StudentDemo {
    //如果参数是一个类名,那么实际需要的是一个具体的对象
    publicvoid method(Student s) {
//调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();
           s.show();
    }
}
class StudentTest {
    publicstatic void main(String[] args) {
           StudentDemo sd = new StudentDemo();
           Student s = new Student();
           sd.method(s);
           //多个匿名对象的写法
           new StudentDemo.method(new Student());
    }
}

3:匿名对象(掌握)

       (1)没有名字的对象(是对象的一种简化表示形式)

       (2)应用场景

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

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

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

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

              B:可以作为实际参数传递。

 

class Student {
       publicvoid show() {
              System.out.println("我爱学习");
       }
}
class StudentDemo {
       publicvoid method(Student s) {
              s.show();
       }
}
class NoNameDemo {
       publicstatic 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修饰成员变量

 

5:封装和private关键字的应用(掌握)

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

       (2)特点:

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

       (3)private的应用:

              以后再写一个类的时候:

                     把所有的成员变量给private了

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

 

class Student {
   //姓名
   privateString name;
   //年龄
   privateint age;
   //姓名获取值
   publicString getName() {
          return name;
   }
   //姓名设置值
   publicvoid setName(String n) {
          name = n;
   }
   //年龄获取值
   publicint getAge() {
          return age;
   }
   //年龄赋值
   publicvoid setAge(int a) {
          age = a;
   }
}
//测试类
class StudentTest {
   publicstatic 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还有其他的应用,明天讲解。

 

class Student {
       privateString name;
       privateint age;
       publicString getName() {
              return name; //这里其实是隐含了this
       }
       publicvoid setName(String name) {
              this.name = name;
       }
       publicint getAge() {
              return age;
       }
       publicvoid setAge(int age) {
              this.age = age;
       }
}
class StudentTest2 {
       publicstatic 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)setXxx()和构造方法给成员变量赋值的标准案例

 

              classStudent {
                     private String name;
                     private int age;
                     public Student(){}
                     public Student(String name,int age) {
                            this.name= name;
                            this.age= age;
                     }
                     public String getName() {
                            returnname;
                     }
                     public void setName(String name) {
                            this.name= name;
                     }
                     public int getAge() {
                            returnage;
                     }
                     public void setAge(int age) {
                            this.age= age;
                     }
              }
              //测试:
              classStudentDemo {
                     public static void main(String[] args) {
                            //方式1
                            Students1 = new Student();
                            s1.setName("林青霞");
                            s1.setAge(27);
                            System.out.println(s1.getName()+"---"+s1.getAge());
                            //方式2
                            Students2 = new Student("刘意",30);
                            System.out.println(s2.getName()+"---"+s2.getAge());
                     }
              }

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

 

classStudent {
       private String name = "林青霞";
       private int age = 27;
       public Student() {
name = "刘意";
Age = 30;
       }    
classStudentDemo {
       public static void main(String[] args) {
              Students1 = new Student();
 }
}

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

       (2)在栈内存为s变量开辟一个空间

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

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

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

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

       (7)数据初始化完毕,然后把堆内存的地址赋值给栈内存的s变量

9:面向对象的练习题(掌握)

       (1)标准的手机类的定义和测试

       (2)Demo类有求和方法,Test类进行测试。

              什么时候定义成员变量?

              当该变量是用来描述一个类的时候。

 

/*
	定义一个类Demo,其中定义一个求两个数据和的方法,
	定义一个测试了Test,进行测试。
	
	变量什么时候定义为成员变量:
		如果这个变量是用来描述这个类的信息的,那么,该变量就应该定义为成员变量。
		
	变量到底定义在哪里好呢?
		变量的范围是越小越好。因为能及时的被回收。
*/

//方式1
/*
class Demo {
	public int sum() {
		int a = 10;
		int b = 20;
		int c = a + b;
		return c;
	}
}
*/
//方式1满足了我们的要求,但是不好。
//因为参与操作的数据现在是固定的。

//方式2
/*
class Demo {
	public int sum(int a,int b) {
		return a + b;
	}
}
*/

//方式2可以满足我们的要求,但是呢我们学习过来面向对象的思想。
//我就再想,a,b可不可以定义为成员变量呢?
//如果可以,我们再改进一版
class Demo {
	int a;
	int b;
	
	public int sum() {
		return a + b;
	}
}
//虽然这种方式可以,并且好像是符合了面向对象的思想。
//但是不好。
//因为我们曾经说过:类是一组相关的属性和行为的集合。
//并且类是通过事物转换过来的
//而类中的成员变量就是事物的属性
//属性是用来描述事物的
//同理:成员变量其实是用来描述类的。

//测试类
class Test {
	public static void main(String[] args) {
		//创建对象
		//方式1测试
		/*
		Demo d = new Demo();
		System.out.println(d.sum());
		*/
		
		//方式2测试
		/*
		Demo d = new Demo();
		int a = 10;
		int b = 20;
		System.out.println(d.sum(a,b));
		*/
		
		//方式3测试
		Demo d = new Demo();
		d.a = 10;
		d.b = 20;
		System.out.println(d.sum());
	}
}

 

       (3)长方形案例

 

/*
	定义一个长方形类,定义 求周长和面积的方法,
	然后定义一个测试了Test2,进行测试。

	长方形的类:
		成员变量:
			长,宽
		成员方法:
			求周长:(长+宽)*2;
			求面积:长*宽
			
	注意:
		import必须出现在所有的class前面。
*/

import java.util.Scanner;

class ChangFangXing {
	//长方形的长
	private int length;
	//长方形的宽
	private int width;
	
	public ChangFangXing(){}
	
	//仅仅提供setXxx()即可
	public void setLength(int length) {
		this.length = length;
	}
	
	public void setWidth(int width) {
		this.width = width;
	}
	
	//求周长
	public int getZhouChang() {
		return (length + width) * 2;
	}
	
	//求面积
	public int getArea() {
		return length * width;
	}
}

class Test2 {
	public static void main(String[] args) {
		//创建键盘录入对象
		Scanner sc = new Scanner(System.in);
		
		System.out.println("请输入长方形的长:");
		int length = sc.nextInt();
		System.out.println("请输入长方形的宽:");
		int width = sc.nextInt();
		
		//创建对象
		ChangFangXing cfx = new ChangFangXing();
		//先给成员变量赋值
		cfx.setLength(length);
		cfx.setWidth(width);
		
		System.out.println("周长是:"+cfx.getZhouChang());
		System.out.println("面积是:"+cfx.getArea());
	}
}

 

       (4)员工案例

 

/*
	需求:
		定义一个员工类,自己分析出几个成员,
		然后给出成员变量,构造方法,getXxx()/setXxx()方法,
		以及一个显示所有成员信息的方法。并测试。

	分析:
		员工
			成员变量:
				员工编号,姓名,年龄
			构造方法:
				无参构造方法
			成员方法:
				getXxx()/setXxx()
				show();
*/
class Employee {
	//员工编号
	private String employeeId;
	//姓名
	private String name;
	//年龄
	private int age;
	
	//构造方法
	public Employee() {}
	
	//getXxx()/setXxx()
	public String getEmployeeId() {
		return employeeId;
	}
	
	public void setEmployeeId(String employeeId) {
		this.employeeId = employeeId;
	}
	
	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("员工编号是:"+employeeId+"的这个人是:"+name+"的年龄是:"+age);
	}
}

class EmployeeTest {
	public static void main(String[] args) {
		//创建对象
		Employee e = new Employee();
		
		//给成员变量赋值
		e.setEmployeeId("czbk9527");
		e.setName("唐伯虎");
		e.setAge(18);
		
		//获取数据
		//System.out.println(e.getEmployeeId()+"---"+e.getName()+"---"+e.getAge());
	
		//我们在Employee类中定义了一个show方法。所以,我们改进一下,使用show方法
		e.show();
	}
}

 

       (5)MyMath案例(自己提供加减乘除并测试)

 

/*
	定义一个类MyMath,提供基本的加减乘除功能,然后进行测试。
*/
import java.util.Scanner;

class MyMath {
	//加法功能
	public int add(int a,int b) {
		return a + b;
	}
	
	//减法功能
	public int sub(int a,int b) {
		return a - b;
	}
	
	//乘法功能
	public int mul(int a,int b){
		return a * b;
	}
	
	//除法功能
	public int div(int a,int b) {
		return a / b;
	}
}

//测试类
class MyMathTest {
	public static void main(String[] args) {
		//创建键盘录入对象
		Scanner sc = new Scanner(System.in);
		
		System.out.println("请输入第一个操作数:");
		int firstNumber = sc.nextInt();
		System.out.println("请输入第二个操作数:");
		int secondNumber = sc.nextInt();
		
		//创建MyMath对象,并使用
		MyMath mm = new MyMath();
		
		System.out.println("加法结果:"+mm.add(firstNumber,secondNumber));
		System.out.println("减法结果:"+mm.sub(firstNumber,secondNumber));
		System.out.println("乘法结果:"+mm.mul(firstNumber,secondNumber));
		System.out.println("除法结果:"+mm.div(firstNumber,secondNumber));
	}
}

 

10:static关键字(掌握)

(1)静态static的特点:

可以修饰成员变量和成员方法。

(2)静态static的特点:

              A:随着类的加载而加载

                     回想main方法。

              B:优先于对象存在

              C:被类的所有对象共享

                     举例:咱们班级的学生应该共用同一个班级编号。

                     其实这个特点也是在告诉我们什么时候使用静态?

                            如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。

                     举例:

                            饮水机(用静态修饰)

                            水杯(不能用静态修饰)

              D:可以通过类名调用

                     其实它本身也可以通过对象名调用。

                     推荐使用类名调用。

                     静态修饰的内容一般我们称其为:与类相关的,类成员

(3)静态的内存图

              静态的内容在方法区的静态区

7. 面向对象 -- 成员与局部变量和封装

(4)静态static关键字注意事项

              A:在静态方法中是没有this关键字的

                     如何理解呢?

                            静态是随着类的加载而加载,this是随着对象的创建而存在。

                            静态比对象先存在。

              B:静态方法只能访问静态的成员变量和静态的成员方法

                            静态方法:

                                   成员变量:只能访问静态变量

                                   成员方法:只能访问静态成员方法

                            非静态方法:

                                   成员变量:可以是静态的,也可以是非静态的

                                   成员方法:可以是静态的成员方法,也可以是非静态的成员方法。

                     简单记:

                            静态只能访问静态。

(5)静态变量和成员变量的区别

              A:所属不同

                     静态变量:属于类,类变量

                     成员变量:属于对象,对象变量,实例变量

              B:内存位置不同

                     静态变量:方法区的静态区

                     成员变量:堆内存

              C:生命周期不同

                     静态变量:静态变量是随着类的加载而加载,随着类的消失而消失

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

              D:调用不同

                     静态变量:可以通过对象名调用,也可以通过类名调用

                     成员变量:只能通过对象名调用

(6)静态的main方法的格式讲解:

              publicstatic void main(String[] args) {...}

              public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。

              static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。

              void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。

              main:是一个常见的方法入口。我见过的语言都是以main作为入口。

              String[]args:这是一个字符串数组。值去哪里了?

                     这个东西到底有什么用啊?怎么给值啊?

                            这个东西早期是为了接收键盘录入的数据的。

                            格式是:

                                   java MainDemo hello world java

                                  javaMainDemo 10 20 30

7. 面向对象 -- 成员与局部变量和封装