xc的java学习日记(Day07:面向对象的方法2)

Day07

VariableDemo

/*

成员变量和局部变量的区别?

    	

A:在类中的位置不同
    成员变量:在类中方法外
    局部变量:在方法定义中或者方法声明上
B:在内存中的位置不同
    成员变量:在堆内存
    局部变量:在栈内存
C:生命周期不同
    成员变量:随着对象的创建而存在,随着对象的消失而消失
    局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
D:初始化值不同
    成员变量:有默认初始化值
-  boolean bool;-False
-  byte bt; - 0
- short st; - 0
- char ch; - 空字符(’\u0000’)
- int i; - 0
- long l; - 0
-  float f; - 0.0
- double d; - 0.0
- String str; - null
    局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。

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

*/

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();	
			
	}
}

形参是类名的问题

ArgsTest

/*

形式参数的问题:
  基本类型:形式参数的改变不影响实际参数
  引用类型:形式参数的改变直接影响实际参数

*/

//形式参数是基本类型
class Demo {
	public int sum(int a,int b) {  
		return a + b;
	}
}

//形式参数是引用类型

class Demo2 {
	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的地址给到了这里
	}
}

NoNameDemo

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

匿名对象的应用场景:
   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());
 	}
}

封装和private关键字

studentdemo

/*

定义一个学生类:
  成员变量: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("--------------");
	}
}

studentTest

/*
 封装和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());
	}
}

PrivateDemo

/*
  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();
	}
}

This关键字

StudentTest

/*
Tips:起名字要做到见名知意。

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());
	}
}

StudentTest2

/*
标准的代码改进版

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());
}
}

PhoneTest

/*
作业:请把手机类写成一个标准类,然后创建对象测试功能。

手机类:
	成员变量:
		品牌: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关键字的内存图解

构造方法

ConstructDemo

/*
构造方法:
给对象的数据进行初始化

格式:
	A:方法名与类名相同
	B:没有返回值类型,连void都没有
	C:没有具体的返回值

*/
class Student {
private String name; //null
private int age; //0

public Student() {
	System.out.println("这是构造方法");
}

}

class ConstructDemo {
public static void main(String[] args) {
//创建对象
Student s = new Student();
System.out.println(s); //Student@e5bbd6
}
}

ConstructDemo2

/*
我们一直在使用构造方法,但是,我们确没有定义构造方法,用的是哪里来的呢?

构造方法的注意事项:
  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();
	}
}

成员方法

StudentDemo

/*
 类的组成:成员变量,成员方法
 今天我们又加入了一个新的成员:构造方法。
  以后再提类的组成:
     成员变量
     构造方法
     成员方法

  根据返回值:
     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);
	}
}

StudentTest

/*
一个标准代码的最终版。

学生类:
  成员变量:
     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();
	}
}

PhoneTest

/*
 标准的手机类练习

手机类:
  成员变量:brand,price,color
  构造方法:无参构造
  成员方法:getXxx()/setXxx()

*/
//定义手机类

class Phone {
	//品牌
	private String brand;
	//价格
	private int price;
	//颜色
	private String color;
	
	//无参构造方法
	public Phone() {}
	
	//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();
		
		//给成员变量赋值
		p.setBrand("诺基亚");
		p.setPrice(199);
		p.setColor("土豪金");
		
		//获取值
		System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+p.getColor());
	}
}

创建对象做了哪些事情

static的内存图解

static关键字

PersonDemo

/*
定义一个人类

  • 姓名和年龄都是变化的,这个我能接收,因为每个人的姓名和年龄是不同的。
  • 但是,我们现在选取的几个人都是中国人,他们的国籍是一样的。
  • 一样的国籍,我每次创建对象,在堆内存都要开辟这样的空间,
  • 我就觉得有点浪费了。怎么办呢?
  • 针对多个对象有共同的这样的成员变量值的时候,
  • Java就提高了一个关键字来修饰:static。

*/

class Person {
	//姓名
	String name;
	//年龄
	int age;
	//国籍
	//String country;
	static String country;

public Person(){}

public Person(String name,int age) {
	this.name = name;
	this.age = age;
}

	public Person(String name,int age,String country) {
		this.name = name;
		this.age = age;
		this.country = country;
	}
	
	public void show() {
		System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+country);
	}
}
class PersonDemo {
	public static void main(String[] args) {
		//创建对象1
		Person p1 = new Person("邓丽君",16,"中国");
		p1.show();
	
	//创建对象2
	//Person p2 = new Person("杨幂",22,"中国");
	//p2.show();
	Person p2 = new Person("杨幂",22);
	p2.show();
	
	//创建对象3
	//Person p3 = new Person("凤姐",20,"中国");
	//p3.show();
	Person p3 = new Person("凤姐",20);
	p3.show();

	p3.country = "美国";
	p3.show();
	
	p1.show();
	p2.show();
}
}	

StudentDemo

/*
  static的特点:(它可以修饰成员变量,还可以修饰成员方法)
    A:随着类的加载而加载
      回想main方法。
   B:优先于对象存在
   C:被类的所有对象共享
      举例:咱们班级的学生应该共用同一个班级编号。
       其实这个特点也是在告诉我们什么时候使用静态?
       如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。
      举例:
       饮水机(用静态修饰)
       水杯(不能用静态修饰)
    D:可以通过类名调用
    其实它本身也可以通过对象名调用。

推荐使用类名调用。

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

*/

class Student {
	//非静态变量
	int num = 10;
	
	//静态变量
static int num2 = 20;

}

class StudentDemo {
	public static void main(String[] args) {
		Student s = new Student();
		System.out.println(s.num);
		
		System.out.println(Student.num2);
		System.out.println(s.num2);
	}

}

TeacherDemo

/*
 static关键字注意事项
   A:在静态方法中是没有this关键字的
     如何理解呢?
     静态是随着类的加载而加载,this是随着对象的创建而存在。
     静态比对象先存在。
   B:静态方法只能访问静态的成员变量和静态的成员方法
     静态方法:
     成员变量:只能访问静态变量
     成员方法:只能访问静态成员方法
   非静态方法:
     成员变量:可以是静态的,也可以是非静态的
     成员方法:可是是静态的成员方法,也可以是非静态的成员方法。

简单记:
     静态只能访问静态。

*/

class Teacher {
	public int num = 10;
	public static int num2 = 20;
	
public void show() {
	System.out.println(num); //隐含的告诉你访问的是成员变量
	System.out.println(this.num); //明确的告诉你访问的是成员变量
	System.out.println(num2);
	
	//function();
	//function2();
}

public static void method() {
	//无法从静态上下文中引用非静态 变量 num
	//System.out.println(num);
	System.out.println(num2);
	
	//无法从静态上下文中引用非静态 方法 function()
	//function();
	function2();
}

public void function() {

}

public static void function2() {
	
	}
}

class TeacherDemo {
	public static void main(String[] args) {
		//创建对象
		Teacher t = new Teacher();
		t.show();
		System.out.println("------------");
		t.method();
	}
}

MainDemo

/*
main方法的格式讲解:
public static void main(String[] args) {…}

  • public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。
  • static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。
  • void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。
  • main:是一个常见的方法入口。我见过的语言都是以main作为入口。
  • String[] args:这是一个字符串数组。值去哪里了?
      这个东西到底有什么用啊?怎么给值啊?
      这个东西早期是为了接收键盘录入的数据的。
    格式是:
      java MainDemo hello world java

*/

class MainDemo {
	public static void main(String[] args) {
		//System.out.println(args); //[Ljava.lang.String;@175078b
		//System.out.println(args.length); //0
		//System.out.println(args[0]); //ArrayIndexOutOfBoundsException
		
		//接收数据后
		System.out.println(args); 
		System.out.println(args.length); 
		//System.out.println(args[0]); 
		for(int x=0; x<args.length; x++) {
			System.out.println(args[x]);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/sdfx11566/article/details/88801737