JAVA基础学习笔记(4):面向过程与面向对象、类的属性、类的方法、构造器、this关键字

1 面向过程

面向过程(POP:Procedure Oriented Programming),强调的是功能行为,以函数为最小单位,考虑怎么做。

2 面向对象

面向对象(OOP:Object Oriented Programming ),将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。

2.1 面向对象的三大特性

封装(Encapsulation) 、继承(Inheritance)、多态(Polymorphism)

2.1 面向对象思路与步骤

(1)根据问题需要,选择问题所针对的现实世界中的实体
(2)从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类
(3)把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构。
(4)将类实例化成计算机世界中的对象。对象是计算机世界中解决问题的最终工具。

2.3 面向对象的两个要素:类和对象

(1)类:类是对一类事物的描述,是抽象的、概念上的定义
(2)对象:对象是实际存在的该类事物的每个个体,因而也称为实例(instance)。

3 类、类的属性、类的方法

3.1 类的语法格式

在这里插入图片描述
属性 = 成员变量 = field = 域、字段
方法 = 成员方法 = 函数 = method
创建类的对象 = 类的实例化 = 实例化类

3.2 类的定义步骤

(1)定义类(考虑修饰符、类名)
(2) 编写类的属性(考虑修饰符、属性类型、属性名、初始化值)
(3) 编写类的方法(考虑修饰符、返回值类型、方法名、形参等)

3.3 类中属性的使用(对比局部变量)

3.3.1 相同点

(1)定义格式: 数据类型 变量名 = 变量值
(2)先声明,后使用
(3)变量都有其相应的作用域

3.3.2 不同点

在类中声明的位置的不同

属性:直接定义在类的一对{}内。
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量。

关于权限修饰符的不同

属性:可以在声明属性时,指明其权限,使用权限修饰符。(public、private、protected、缺省)
局部变量:不可以使用权限修饰符。

默认初始化值的情况

属性:类的属性,根据其类型,都有默认初始化值。[引用数据类型(类、数组、接口):null]
局部变量:没有默认初始化值。

在内存中加载的位置

属性:加载到堆空间中。(非static)
局部变量:加载到栈空间。
在这里插入图片描述

3.4 类中方法的使用

3.4.1 方法的声明格式

在这里插入图片描述

3.4.2 需要注意的地方

方法的使用中,可以调用当前类的属性或方法

3.5 类和对象的创建和使用

/**
 * 功能:设计类并创建对象,调用其中的属性和方法
 * @author wuzec
 *
 */
public class PersonTest {
	public static void main(String[] args) {
		//创建Person对象
		Person p1 = new Person();
		
		//调用属性
		p1.age = 10;
		p1.isMale = true;
		p1.name="Wu";
		System.out.println(p1.name);
		
		//调用方法
		p1.eat();
		p1.sleep();
		p1.talk("Chinese");
	}
}

class Person{
	
	//属性
	String name;
	int age;
	boolean isMale;
	
	//方法
	public void sleep() {
		System.out.println("sleeping");
	}
		
	public void eat() {
		System.out.println("eating");
	}
	
	public void talk(String language) {
		System.out.println("talk using " + language);
	}
}

3.6 类和对象的内存解析

3.6.1 JVM内存详细解析

在这里插入图片描述
堆(Heap):此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。所有的对象实例以及数组都要在堆上分配。
栈(stack):指的是虚拟机栈,用于存储局部变量等。 局部变量表存放了编译期可知长度的各种基本数据类型、对象引用。 方法执行完,自动释放。
方法区(Method Area):用于存储已被虚拟机加载的类信息、常量、静态 变量、即时编译器编译后的代码等数据。

3.6.2 对象的内存解析

在这里插入图片描述

/**
 * 功能:内存解析的一个小例子
 * @author wuzec
 *
 */
public class PersonTest {
	public static void main(String[] args) {
		//创建Person对象
		Person p1 = new Person();
		
		//调用属性
		p1.age = 10;
		p1.isMale = true;
		p1.name="Wu";
		System.out.println(p1.name);
		
		
		Person p2 = new Person();
		p2 = p1; //p1对象的指针,传到p2中,p1与p2指向同一个区域
		System.out.println(p2.name); //Wu
		System.out.println(p2.age);//10
		System.out.println(p2.IsMale);//true	
	}
}

class Person{
	String name;
	int age;
	boolean isMale;

	public void sleep() {
		System.out.println("sleeping");
	}
	
	public void eat() {
		System.out.println("eating");
	}
	
	public void talk(String language) {
		System.out.println("talk using " + language);
	}
}

4 进一步谈类方法

4.1 方法重载

在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
“两同一不同”:同一个类、方法名相同;参数列表不同,参数个数不同,参数类型不同。
判断是否重载与方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系。

/**
 * 功能:测试方法重载
 * @author wuzec
 *
 */
public class OverloadTest {
	public static void main(String[] args) {
		OverloadTest t1 = new OverloadTest();
		t1.getSum(1, 1);  //1
		t1.getSum(1.2, 2.2);  //2
		t1.getSum(1, 2, 0.1);  //3
		t1.getSum(1, 2, 3); //4 
	}
	
	public void getSum(int a, int b) {
		System.out.println("1");
	}
	
	public void getSum(double a, double b) {
		System.out.println("2");
	}
	
	public void getSum(int a, int b, double c) {
		System.out.println("3");
	}
	
	public int getSum(int a, int b, int c) {
		System.out.println("4");
		return 0;
	}
}

4.2 可变形参的方法

可变个数形参的格式:数据类型 … 变量名
当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,n个
可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存。
可变个数形参在方法的形参中,必须声明在末尾。
可变个数形参在方法的形参中,最多只能声明一个可变形参。

/**
 * 功能:测试可变行参的方法
 * @author wuzec
 *
 */
public class MethodArgsTest {
	public static void main(String[] args) {
		MethodArgsTest t1 = new MethodArgsTest();
		t1.show(); //1
		t1.show("hhah"); //2
		t1.show("hahah", "world", "nini"); //3
		t1.show(1, "hello","world"); //4	
	}
	
	public void show() {
		System.out.println("1");
	}
	
	public void show(String s) {
		System.out.println("2");
	}
	
	//jdk 5.0 之后的新特性
	public void show(String ... strs) {
		System.out.println("3: show(String .. str)");	
		//strs可以看成数组的处理方式
		for(int i=0; i < strs.length; i++) {
			System.out.println(strs[i]);
		}
	}
	
//  在jdk 5.0之前使用此方式来进行可变参数方法	
//	public void show(String[] args) {
//		
//	}
	
	//可变形参必须放在参数列表的最后,并且只能有一个
	public void show(int a, String ...strs) {
		System.out.println("4");
	}
}

4.3 方法参数的值传递机制

形参:方法声明时的参数
实参:方法调用时实际传给形参的参数值
Java里方法的参数传递方式只有一种:值传递。 即将实际参数值的副本 (复制品)传入方法内,而参数本身不受影响。

4.3.1 变量赋值的本质

如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。

/**
 * 功能:测试基本数据类型和引用数据类型变量赋值的本质
 * @author wuzec
 *
 */
public class ValueTransferTest {
	public static void main(String[] args) {
		System.out.println("************基本数据类型******************");
		int m = 10;
		int n = m; //n变量在栈中  存储的为m变量中的值
		System.out.println("m = " + m + ", n = " + n);//m = 10, n = 10
		n = 20;
		System.out.println("m = " + m + ", n = " + n);//m = 10, n = 20
		
		System.out.println("************引用数据类型******************");
		Item i1 = new Item();
		i1.id = 100;
		
		Item i2 = new Item();
		i2 = i1;  //i2变量接收的是i1对象所指向的地址值,所以他们在内存中的位置是一样的
		System.out.println("i1.id = " + i1.id + ", i2.id = " + i2.id);//i1.id = 100, i2.id = 100
		i2.id = 200;
		System.out.println("i1.id = " + i1.id + ", i2.id = " + i2.id);//i1.id = 200, i2.id = 200
	}
}
class Item{
	int id;
}

4.3.2 值传递机制

值传递机制:
如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。

/**
 * 功能:测试值传递机制
 * @author wuzec
 *
 */
public class ValueTransferTest1 {
	public static void main(String[] args) {
		System.out.println("********基本数据类型**********");
		int m = 10;
		int n = 20;
		System.out.println("m = " + m + ", n = " + n );//m = 10, n = 20
		ValueTransferTest1 test = new ValueTransferTest1();
		test.swap1(m, n);
		System.out.println("m = " + m + ", n = " + n );//m = 10, n = 20
		
		System.out.println("********引用数据类型**********");
		Data d1 = new Data();
		d1.m = 10;
		d1.n = 20;
		System.out.println("m = " + d1.m + ",n = " + d1.n);//m = 10,n = 20
		test.swap2(d1);
		System.out.println("m = " + d1.m + ",n = " + d1.n);//m = 20,n = 10
	}
	
	void swap1(int i, int j) {
		int temp = i;
		i = j;
		j = temp;
	}
	
	void swap2(Data d1) {
		int temp = d1.m;
		d1.m = d1.n;
		d1.n = temp;
	}
}

class Data{
	int m;
	int n;
}

4.4 递归方法

一个方法体内调用它自身。

5 封装与隐藏

在进行程序设计中,要遵循“高内聚,低耦合”的原则。
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提 高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思想。

5.1 信息的封装与隐藏

Java中通过将数据声明为私有的(private),再提供公共的(public) 方法:getXxx()和setXxx()实现对该属性的操作

/**
 * 功能:get方法与set方法
 * @author wuzec
 *
 */
public class AnimalTest {

	public static void main(String[] args) {
		Animal a = new Animal();
		a.setName("tiger");
		a.setAge(15);
		System.out.println("名字为:" + a.getName());
		System.out.println("年龄为" + a.getAge() );
	}
}

class Animal{
	private String name;
	private int age;
	
	//get  set方法
	public String getName(){
		return name;
	}
	
	public void setName(String s){
		name = s;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int a) {
		age = a;
	}
}

5.2 访问权限修饰符

4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类。
修饰类只能用:缺省、public
在这里插入图片描述

5.3 构造器

5.3.1 构造器的作用

创建对象,给对象进行初始化

5.3.2 构造器的类型

隐藏式的无参构造器(系统默认提供)
显示定义一个多个构造器(有参、无参)

5.3.2 构造器的使用

1.如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
2.定义构造器的格式:权限修饰符 类名(形参列表){}
3.一个类中定义的多个构造器,彼此构成重载
4.一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
5.一个类中,至少会有一个构造器。

/**
 * 功能:构造器的使用
 * @author wuzec
 *
 */
public class PersonATest {
	public static void main(String[] args) {
		PersonA p1 = new PersonA();//PersonA()......
		PersonA p2 = new PersonA("uzi");
		PersonA p3 = new PersonA(12);
		PersonA p4 = new PersonA("uzi", 12);
		
		p1.show();// name = null, age = 0
		p2.show();// name = uzi, age = 0
		p3.show();// name = null, age = 12
		p4.show();//  name = uzi, age = 12	
	}
}

class PersonA{
	//属性
	String name;
	int age;
	
	//构造器
	public PersonA(){
		System.out.println("PersonA()......");
	}
	
	public PersonA(String str) {
		name = str;
	}
	
	public PersonA(int a) {
		age = a;
	}
	
	public PersonA(String str, int a) {
		name = str;
		age = a;
	}
	
	//方法
	public void eat() {
		System.out.println("eating....");
	}
	
	public void show() {
		System.out.println(" name = " + name + ", age = " + age);
	}
}

5.4 this关键字的使用

this关键字可以修饰属性、方法、构造器。
this理解为:当前对象 或 当前正在创建的对象。

5.4.1 this修饰属性、方法

在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。但是,通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式使用"this.变量"的方式,表明此变量是属性,而非形参。

/**
 * 功能:this关键字的修饰属性与方法
 * @author wuzec
 *
 */
public class PersonBTest {
	public static void main(String[] args) {
		PersonB p1 = new PersonB();
		p1.setName("张三");
		p1.setAge(15);
		System.out.println("p1 的形名为 "+ p1.getName() + ", 年龄为 "+ p1.getAge());
		p1.eat();
	}

}

class PersonB{
	//属性
	String name;
	int age;
	
	//构造器
	public PersonB() {
		
	}
	
	public PersonB(String name, int age){
		this.name = name;
		this.age = age;
	}
	
	//set、get方法
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return this.name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public int getAge() {
		return this.age;
	}
	
	//方法
	public void study() {
		System.out.println("studying.....");
	}
	
	public void eat() {
		System.out.println("eating.....");
		this.study();
	}
}

5.4.2 this调用构造器

在类的构造器中,可以显式的使用"this(形参列表)"方式,调用本类中指定的其他构造器。
构造器中不能通过"this(形参列表)“方式调用自己。
如果一个类中有n个构造器,则最多有 n - 1构造器中使用了"this(形参列表)”。
规定:"this(形参列表)“必须声明在当前构造器的首行。
构造器内部,最多只能声明一个"this(形参列表)”,用来调用其他的构造器。

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

本节练习

ex1

在这里插入图片描述
Person.java:

public class Person {
	String name;
	int age;
	int sex;
	
	public void study(){
		System.out.println("studying");
	}
	
	public void showAge() {
		System.out.println(age);
	}
	
	public int addAge(int i){
		age = age + i;	
		return age;
	}
}

PersonTest.java:

public class PersonTest {
	public static void main(String[] args) {
		Person p1= new Person();
		p1.name = "Tom";
		p1.age = 10;
		p1.sex = 1;

		p1.study();
		p1.showAge();
		p1.addAge(5);
		p1.showAge();
	}
}

ex2

在这里插入图片描述

package newquestion;
/**
 * 功能:ex2 解法
 * @author wuzec
 *
 */
public class StudentTest {
	public static void main(String[] args) {
		Student[]  stus = new Student[20];
		
		for(int i = 0; i < stus.length; i++) {
			//给数组元素赋值
			stus[i] = new Student();
			//给Student对象的属性赋值
			stus[i].number = (i + 1);
			//年级[1,6]
			//求[n,m]随机数 Math.random()*(m-n+1)+1
			stus[i].state = (int)(Math.random() * (6 - 1 + 1) + 1);
			stus[i].score = (int)(Math.random() * (100 - 0 + 1) + 1);
		}
		
		//遍历数组
		for(int i = 0; i < stus.length; i++) {
			System.out.println(stus[i].info());
		}
		System.out.println();
		
		//打印三年级的学生信息
		for(int i = 0; i < stus.length; i++) {
			if(stus[i].state == 3) {
				System.out.println(stus[i].number + "学生的三年级,成绩为" + stus[i].score);
			}
		}
		
		//按照成绩进行排序
		for(int i = 0; i < stus.length - 1; i++) {
			for(int j = 0; j<stus.length - i - 1; j++) {
				if(stus[j].score > stus[j + 1].score) {
					Student temp = stus[j];
					stus[j] = stus[j + 1];
					stus[j + 1] = temp;
				}
			}
		}
		System.out.println();
		
		
		for(int i = 0; i < stus.length; i++) {
			System.out.println(stus[i].info());
		}
	}
}

class Student{
	int number; //学号
	int state; //年级
	int score;
	
	public String info() {
		return "学号:" + number + ",年级:" + state + ",成绩:"+ score ;
	}
}

ex3

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Account.java:

package newquestion;

public class Account {
	private int id;//帐号
	private double balance;//余额
	private double annuallnterestRate;//年利率
	
	public Account(int id, double balance,double annuallnterestRate) {
		this.id = id;
		this.balance = balance;
		this.annuallnterestRate = annuallnterestRate;
	}
	
	public int getId() {
		return this.id;
	}
	
	public double getBalance() {
		return this.balance;
	}
	
	public double getAnnuallnterestRate() {
		return this.annuallnterestRate;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	public void setBalance(double balance) {
		this.balance = balance;
	}
	
	public void setAnnuallnterestRate(double annuallnterestRate) {
		this.annuallnterestRate = annuallnterestRate;
	}
	
	//取钱
	public void withdraw(double amount) {
		if(amount < balance) {
			balance = balance - amount;
			System.out.println("成功取出 " + amount +"元, 账户余额为 " + balance + "元");
		}
		else {
			System.out.println("账户余额不足");
		}
	}
	
	//存钱
	public void deposit(double amount) {
		balance = balance + amount;
		System.out.println("成功存入 "+ amount + "元,账户余额为" + balance + "元");	
	}
}

Customer.java:

package newquestion;

public class Customer {
	private String firstName;
	private String lastName;
	private Account account;

	public Customer(String f, String l) {
		this.firstName = f;
		this.lastName = l;
	}
	
	public String getFirstName() {
		return this.firstName;
	}
	
	public String getLastName() {
		return this.lastName;
	}
	
	public Account getAccount(){
		return this.account;
	}
	
	public void setAccount(Account account) {
		this.account = account;
	}
}

AccAndCusTest.java:

package newquestion;

public class AccAndCustTest {
	public static void main(String[] args) {
		Customer c1 = new Customer("Jana","Smith");
		Account a1 = new Account(1000,2000,0.0123);
		c1.setAccount(a1);
		c1.getAccount().deposit(100);
		c1.getAccount().withdraw(960);
		c1.getAccount().withdraw(2000);
		
		System.out.println("Customer " + "["+ c1.getFirstName() + c1.getLastName() + "]" 
				+ "has a account: id is " + c1.getAccount().getId() + " annualInterestRate is " 
				+ c1.getAccount().getAnnuallnterestRate()*100 + "%, balance is " 
				+ c1.getAccount().getBalance());
	}
}

ex4

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Account.java:

package ex2;

public class Account {
	private double balance;
	
	public Account(double balance) {
		this.balance = balance;
	}
	
	public  double getBalance() {
		return this.balance;
	}
	//存款
	public void deposit(double amt) {
		if(amt >0) {
			balance += amt;
			System.out.println("存钱成功,余额为" + balance );
		}
	}
	//取款
	public void withdraw(double amt) {
		if(amt > balance) {
			System.out.println("取款失败,余额不足");
		}
		else {
			balance -= amt;
			System.out.println("取款成功,余额为"+balance);
		}	
	}
}

Customer.java:

package ex2;

public class Customer {
	private String firstName;
	private String lastName;
	private Account account;
	
	public Customer(String firstName, String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;
	}

	public String getFirstName() {
		return firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public Account getAccount() {
		return account;
	}

	public void setAccount(Account account) {
		this.account = account;
	}
}

Bank.java:

package ex2;

public class Bank {
	private Customer[] customers;// 存放多个数组
	private int numberOfCustomer;//记录客户的个数
	
	public Bank() {
		customers = new Customer[10];	
	}
	//添加用户
	public  void addCustomer(String f, String l) {
		Customer cust = new Customer(f,l);
		customers[numberOfCustomer++] = cust;
	}
	//获取用户个数
	public int getNumOfCustomers() {
		return numberOfCustomer;
	}
	//获取指定位置上的用户
	public Customer getCustomer(int index) {
		if(index>=0 && index < numberOfCustomer){
			return  customers[index];
		}
			return null;		
	}
}

BankTest.java:

package ex2;

public class BankTest {
	public static void main(String[] args) {
		Bank bank = new Bank();
		
		bank.addCustomer("Jane", "Smith");
		
		//连续操作
		bank.getCustomer(0).setAccount(new Account(2000));
		bank.getCustomer(0).getAccount().withdraw(500);
		
		double balance = bank.getCustomer(0).getAccount().getBalance();
		System.out.println("客户:"+bank.getCustomer(0).getFirstName() + "的账户余额为:" + balance);
		System.out.println("***********************");
		bank.addCustomer("万里", "杨");
		
		System.out.println("银行客户的个数为:" + bank.getNumOfCustomers());
	}
}

参考资料:
[1]尚硅谷宋康红java基础教程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值