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

Java编程 面向对象详讲

程序员文章站 2022-03-11 09:21:35
面向对象上篇*## 1.类与对象1.1看一个养猫猫问题1.2 java语言是面向对象的计算机语言的发展向接近人的思维方式演变(能编写功能更多软件):汇编语言 [面向机器] 有助记符 load return …c语言 [面向过程] 函数=> 完成功能java语言 [面向对象] 类与对象 => 编写更加复杂,大型软件汇编语言(汇编 不会编,不会编汇编)=> 驱动程序1.3类与对象的关系示意图1.4 快速入门-面向对象的方式解决养猫问...

面向对象上篇*

## 1.类与对象

1.1看一个养猫猫问题Java编程 面向对象详讲

1.2 java语言是面向对象的
计算机语言的发展向接近人的思维方式演变(能编写功能更多软件):
汇编语言 [面向机器] 有助记符 load return …
c语言 [面向过程] 函数=> 完成功能
java语言 [面向对象] 类与对象 => 编写更加复杂,大型软件

		汇编语言(汇编 不会编,不会编汇编)=> 驱动程序

1.3类与对象的关系示意图
Java编程 面向对象详讲

1.4 快速入门-面向对象的方式解决养猫问题

import java.util.Scanner;
public class OOPTest
{
	public static void main(String[] args) {
		// int num1 = 20;
		Cat cat1 = new Cat();
		cat1.name = "小白";
		cat1.age = 3;
		cat1.color = "白色";
		System.out.println("猫的信息:" + cat1.name + " " + cat1.age + " " + cat1.color);	
	}
}
//定义一个猫类(数据类型)
class Cat //Cat.class
{
	//属性
	String name; // null
	int age;//0
	String color;//null

	//行为 =》 方法
}
class Car
{
	//属性,成员变量,字段
	String  name;
	double price;
	String color;
}

1.5类和对象的区别和联系
通过上面的案例和讲解我们可以看出:

1)类是抽象的,概念的,代表一类事物,比如人类,猫类…, 即它是数据类型.
2)对象是具体的,实际的,代表一个具体事物, 即 是实例.
3)类是对象的模板,对象是类的一个个体,对应一个实例

1.6对象在内存中存在的形式

Java编程 面向对象详讲

1.7属性/成员变量
基本介绍

1)从概念或叫法上看: 成员变量 = 属性 = field (即 成员变量是用来表示属性的,授课中,统一叫 属性)
案例演示:Car(name,price,color)

2)属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对象,数组)。比如我们前面定义猫类 的 int age 就是属性

属性的注意事项和细节
Java编程 面向对象详讲

import java.util.Scanner;
public class ProDetail
{
	public static void main(String[] args) {
		
			int num = 100;
		
			/*
			属性如果不赋值,有默认值,规则和数组一致。
			案例演示:[Cat, Dog] //int 	0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,
			boolean false,String null , 即只有是引用类型,统统为null
			*/
			Cat myCat = new Cat();
			System.out.println("默认值 " + myCat.name + " " + myCat.age + " " + myCat.color);

			Cat myCat2 = new Cat();
			myCat2.name = "小白"; 
			System.out.println("mycat " + myCat.name + " " + myCat.age + " " + myCat.color);
			System.out.println("mycat2 " + myCat2.name + " " + myCat2.age + " " + myCat2.color);
	}
}

//定义一个猫类(数据类型)
class Cat
{
	//属性
	String name;
	int age;
	String color;
	//行为 =》 方法
}

1.8类和对象的内存分配机制(重要)
Java编程 面向对象详讲
Java编程 面向对象详讲

1.9Java内存的结构分析
1)栈: 一般存放基本数据类型(局部变量)
2)堆: 存放对象(Cat cat , 数组等)
3)方法区:常量池(常量,比如字符串), 类加载信息
4)示意图 [Cat (name, age, price)]

1.10java创建对象的流程简单分析
Java编程 面向对象详讲
1)先加载Person 类 , 只会加载一次
2)在堆中,分配空间[地址],并进行默认初始化,比如 name=null age = 0
3)把堆中地址,返回给 p1
4)进行指定初始化 name = “jack” age = 10
5)开始使用p1

1.11类和对象的内存分配机制-练习题

Java编程 面向对象详讲

Java编程 面向对象详讲

2成员方法

2.1基本介绍

在某些情况下,我们要需要定义成员方法。比如人类:除了有一些属性外( 年龄,姓名…),我们人类还有一些行为比如:可以说话、跑步…,通过学习,我们人类还可以做算术题。这时就要用成员方法才能完成。现在要求对Cat类完善。

2.2成员方法快速入门

1)添加speak 成员方法,输出 我是一只好猫
2)添加jisuan 成员方法,可以计算从 1+…+1000的结果
3)添加cal 成员方法,该方法可以接收一个数n,计算从 1+…+n 的结果
4)添加getSum成员方法,可以计算两个数的和
5)代码:

import java.util.Scanner;

//成员方法的使用
public class MethodTest
{
	public static void main(String[] args) {
		//调用方法
		//1. 创建对象
		Cat myCat = new Cat();
		//2. 调用方法
		myCat.speak();
		myCat.jisuan();
		System.out.println("请输入一个整数");
		Scanner myScanner = new Scanner(System.in);
		int num = myScanner.nextInt();
		myCat.cal(num); // 20 称为 实际参数(实参)
		myCat.getSum(30, 100);
	}
}

//定义一个猫类(数据类型)
class Cat //Cat.class
{
	//属性
	String name; // null
	int age;//0
	String color;//null

	//行为 =》 方法
	//添加speak 成员方法,输出 我是一只好猫
	//解读
	//1. public 表示公开方法
	//2. void 没有返回值
	//3. speak 方法名, () 没有形参
	//4 { } 称为方法体
	//5. 写入你的代码
	public void speak() {
		System.out.println("我是一只好猫");
	}

	//添加jisuan 成员方法,可以计算从 1+..+1000的结果
	public void jisuan() {
		int sum = 0;
		for( int i = 1; i <= 1000; i++) {
			sum += i;
		}
		System.out.println("sum=" + sum);
	}
	//传递参数
	//添加cal 成员方法,该方法可以接收一个数n,计算从 1+..+n 的结果
	//传递参数
	//术语 :int n 称为 形式参数(形参)
	public void cal(int n) {
		int sum = 0;
		for( int i = 1; i <= n; i++) {
			sum += i;
		}
		System.out.println("sum=" + sum);
	}
	//添加getSum成员方法,可以计算两个数的和
	public void getSum(int n1, int n2) {
		int sum = n1 + n2;
		System.out.println("和=" + sum);
	}
}

2.3方法的调用机制原理:(重要!!!)
提示:画出程序执行过程[cal]+说明

2.4为什么需要成员方法
看一个需求:
请遍历一个数组 , 输出数组的各个元素值。
解决思路1,传统的方法,就是使用单个for循环,将数组输出,大家看看问题是什么?

解决思路2: 定义一个类 MyTools ,然后写一个成员方法,看看效果又如何。

代码如下

import java.util.Scanner;

//成员方法的使用
public class WhyMethod
{
	public static void main(String[] args) {
		int[] arr1 = {1, 2, 50, 900, 900, -12};
		//创建MyTools对象
		MyTools tools = new MyTools();
		tools.printArr(arr1);
		int[] arr2 = {1, 2, 50, 900, 900, -12, 10000};
		tools.printArr(arr2);
		int[] arr3 = {1, 2, 50, 900, 900};
		tools.printArr(arr3);
	}
}
class  MyTools //工具类
{
	public void printArr(int[] arr) { //方法
		
		System.out.println();
		for( int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + ", ");
		}
	}
}

2.5成员方法的好处

1)提高代码的复用性
2)可以将实现的细节封装起来,然后供其他用户来调用即可。!!!

2.6成员方法的定义
Java编程 面向对象详讲

2.7注意事项和使用细节
修饰符 (作用是控制 方法使用的范围)
可选,如果不写就是默认的 [public > protected > 默认 > private], 具体在后面说
返回类型
1)一个方法至多有一个返回值 [思考,如何返回多个结果, 数组]
2)返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
3)如果方法有返回值,则方法体中最后的执行语句必须为return语句,而且要求返回类型必须和return的值类型一致或兼容
4)如果方法没有返回值,则方法体中可以没有return语句,返回类型要求写void
方法名
遵循驼峰命名法,最好见名知义,表达出该功能的意思即可, 比如 得到两个数的和 getSum, 开发中按照规范
参数列表

  1. 一个方法可以有0个参数,也可以有多个参数,中间用逗号隔开(类型 名,类型 名) 【getMax , 比如得到三个数的最大值 】

  2. 参数类型可以为任意类型,包含基本类型或引用类型 【test100】

  3. 调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型 的参数!【test200】
    4)方法定义时的参数称为形式参数,简称形参;方法调用时的参数称为实际参数,简称实参,实参和形参的类型(兼容)、个数、顺序必须一致!
    方法体
    里面写完成功能的具体的语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但里面不能再定义方法!即:方法不能嵌套定义。[test400]
    成员方法的调用说明

  4. 同一个类中的方法调用:直接调用即可。比如 print(参数);
    案例演示:A类 sayOk 调用 print()

  5. 跨类中的方法A类调用B类方法:需要通过对象名调用。比如 对象名.方法名(参数); 案例演示:B类 sayHello 调用 print()
    代码

import java.util.Scanner;
public class MethodDetail
{
	public static void main(String[] args) {
		
		//一个方法至多有一个返回值  [思考,如何返回多个结果, 数组.]

		//创建对象
		Cat myCat = new Cat();
		//解读
		//1. myCat.m1(4) 返回一个int 结果
		int res = myCat.m1(5);
		System.out.println("res=" + res);

		//2. 测试数组
		// myCat.m2(1, 4) 返回一个数组
		int[] reses = myCat.m2(1, 4);
		System.out.println("和=" + reses[0]);
		System.out.println("差=" + reses[1]);


		//public void m6(int n1, double d1, int[] arr) 
		int[] arr = {};
		myCat.m6(10, 1, arr);

		//测试
		A aObj = new A();
		aObj.sayOk();
	}
}

class B
{
	public void sayHello() {
		//需要通过对象名调用
		A aObj = new A();
		aObj.sayHi();
	}
}

class A
{
	//同一个类中的方法调用:直接调用即可
	public void sayHi() {
		System.out.println("say hi");
	}
	public void sayOk() {
		sayHi();
		System.out.println("say ok");
	}
}
class Cat
{
	//一个方法至多有一个返回值  [思考,如何返回多个结果, 数组.]
	public int m1(int n) {
		return 2 * n;
	}
	public int[] m2(int n1, int n2) {	
		//创建一个数组
		int[] res = new int[2];
		res[0] = n1 + n2;
		res[1] = n1 - n2;
		return res;
	}
	//如果方法有返回值,则方法体中最后的执行语句必须为return语句,
	//而且要求返回类型必须和return的值类型一致或兼容

	public int m3() {
		return (int)1.1;
	}
	//如果方法没有返回值,则方法体中可以没有return语句,返回类型要求写void
	public void m4() { 
	
	}
	//参数类型可以为任意类型,包含基本类型或引用类型
	public void m5(int n, int[] arr) {
		
	}

	//调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型 的参数!
	public void m6(int n1, double d1, int[] arr) {
		//方法体.
		//调用其他方法...
	}	
	//方法不能嵌套定义
	public void m7() {
		
//		public void m8() {
//			
//		}
	}
}

3 成员方法传参机制

3.1基本数据类型的传参机制
看一个案例
编写一个方法,交换两个整数的值。

import java.util.Scanner;

//基本数据类型传递
public class MethodPassPara01
{
	public static void main(String[] args) {
		
		T2 t2 = new T2();
		int a = 30;
		int b = 50;
		t2.swap(a, b);
		System.out.printf("a=%d b=%d\n", a, b);
	}
}

class T2
{
	public void swap( int num1, int num2) {
		
		System.out.println("swap方法中...");
		System.out.printf("num1=%d num2=%d\n", num1, num2);
		int temp = 0;
		temp = num1;
		num1 = num2;
		num2 = temp;
		System.out.printf("num1=%d num2=%d\n", num1, num2);
	}
}
  • 结论及示意图 基本数据类型,传递的是值(元素内容, 值拷贝), 形参的任何改变不影响实参!
  • 示意图
    Java编程 面向对象详讲

3.2引用数据类型的传参机制

  • 看一个案例
    B类中编写一个方法test100,可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化?
    B类中编写一个方法test200,可以接收一个Person(age,sal)对象,在方法中修改该对象属性,看看原来的对象是否变化?
import java.util.Scanner;
//基本数据类型传递
public class MethodPassPara02
{
	public static void main(String[] args) {
		int[] arr = {1,2,3};
		T3 t3 = new T3();
		t3.test100(arr);
		//看看 arr 的情况
		for( int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + "\t");
		}
	}
}
class T3
{
	public void test100(int[] arr ) {
		
		arr[0] = 100;
	}
}

结论及示意图

引用类型传递的是值(地址),可以通过形参影响实参
Java编程 面向对象详讲

  • 再看一个案例,下面的方法会对原来的对象有影响吗?
    p=null 和 p = new Person(); 对应示意图
import java.util.Scanner;

//基本数据类型传递
public class MethodPassParaExer01
{
	public static void main(String[] args) {
		
		Person p = new Person();
		p.name = "tom";
		p.age = 12;
		T5 t5 = new T5();
		//t5.m1(p);
		//t5.m2(p);
		t5.m3(p);
		System.out.println(p.name + " " + p.age);// tom, 12
	}
}

class Person
{
	String name;
	int age;
}

class T5
{
	public void m3(Person p) {
		p = new Person();
		p.age = 500;
	}

	public void m1(Person p) {
		p.age = 100;
	}

	public void m2(Person p) {
		p = null;
	}
}

3.3成员方法返回类型是引用类型应用实例
先练习
1)编写类MyTools类,编写一个方法可以打印二维数组的数据。
2)编写一个方法copyArray,可以复制一个数组,返回复制的数组。
扩展:可以接收一个参数,指定拷贝原数组的多少个元素。
比如:{1,2, 0, 78, 999}
3)编写一个方法copyPerson,可以复制一个Person对象,返回复制的对象。克隆对象。。, 注意得到新对象和原来的对象是两个独立的对象,只是他们的属性相同
代码

import java.util.Scanner;

//基本数据类型传递
public class MethodPassParaExer02
{
	public static void main(String[] args) {
		int[] arr = {1, 2, 3, 4, 5};
		MyTools mt = new MyTools();
		int[] arrNew = mt.copyArray(arr, -1);

		for( int i = 0; i < arrNew.length; i++) {
			System.out.print(arrNew[i] + "\t");
		}
	}
}
class Person
{
	String name;
	int age;
}

//编写类MyTools类,编写一个方法可以打印二维数组的数据
class MyTools
{
	public void printArr(int[][] arr) {
		for( int i = 0; i <  arr.length; i++) {
			for( int j = 0; j < arr[i].length; j++) {
				System.out.print(arr[i][j] + "\t");
			}
			System.out.println();
		}
	}

	//编写一个方法copyArray,可以复制一个数组,返回复制的数组
	//扩展:可以接收一个参数,指定拷贝原数组的多少个元素
	public  int[] copyArray(int[] arr, int size) {
		//求出实际应该拷贝几个元素
		//程序员 你想如何处理....
		int len = size > arr.length || size <=0  ? arr.length : size; 
		
		
//		int[] arrNew = new int[arr.length];
		int[] arrNew = new int[len];

		for( int i = 0; i < len; i++) {
			arrNew[i] = arr[i];
		}
		return arrNew;
	}

	//拷贝一个Person 
	public Person copyPerson(Person p) {
		//创建一个新人
		Person newPerson = new Person();
		newPerson.name = p.name;
		newPerson.age = p.age;

		return newPerson;
	}
}

补充:public 类也可以写方法,并在 main 创建对象,调用方法

import java.util.Scanner;

//基本数据类型传递
public class ObjectUse //类
{
	public static void main(String[] args) {

		//使用
		ObjectUse ou = new ObjectUse();
		ou.sayHi();
		
	}

	//方法
	public void sayHi() {
		System.out.println("say hi");
	}

	public void sayOk() {
		sayHi();
	}
}

4方法的重载(OverLoad)

4.1基本介绍
java中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致!
比如:System.out.println(); out是PrintStream类型

4.2重载的好处
1)减轻了起名的麻烦
2)减轻了记名的麻烦

4.3重载的快速入门案例
看一个案例
【要求:类名MyPrint,方法名为print,可以打印 等边三角形,矩形,立方体。示意】

public class OverLoadTest
{
	public static void main(String[] args) {
		
		MyPrint mp = new MyPrint();
		mp.print(10);
		mp.print(1, 2, 3);
		
	}

}

//要求:类名MyPrint,方法名为print,可以打印 等边三角形,矩形,立方体。示意
class MyPrint {

	public void print(int len) {
		System.out.println("打印 等边三角形 边长=" + len);
	}

	

	public void print(int len, int width) {
		System.out.println("打印 矩形 长=" + len + " 宽=" + width);
	}

	public void print(int len, int width, int height) {
		System.out.println("打印 立方体 长=" + len + " 宽=" + width + " 高=" + height);
	}
	
}

4.4注意事项和使用细节

1)方法名 :必须相同
2)参数列表:必须不同(参数类型或个数或顺序,至少有一样不同,参数名无要求)
3)返回类型:无要求

案例:类:MyCalculator 方法:calculate
calculate(int n1, int n2)
calculate(int n1, double n2)
calculate(double n2, int n1)
calculate(int n1, int n2,int n3)

5 可变参数

5.1基本概念

jdk5.0出现的新特性,java提供了一种机制,可以允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。

5.2基本语法
访问修饰符 返回类型 方法名(数据类型… 形参名){
}

5.3快速入门案例(VarArgusDemo.java)
看一个案例 类 MethodUtils,方法 sum 【可以计算 2个数的和,3个数的和 , 4. 5, 。。】
utils 工具集
代码

//演示可变参数使用
public class VarArgs
{
	public static void main(String[] args) {
		VarArgs va = new VarArgs();
		double res1 = va.sum(1, 2, 3, 9, 1.1);
		System.out.println("res1=" + res1);
		double[] arr = {1,2,4};
		double res2 = va.sum(arr);
	}

	//演示可变参数使用
	//说明
	//1. double... 后面的三个小点,是规定
	//2. 这时 args 称为 可变形参
	//3. args 可变形参的本质就是数组
	//4. 实参可以传递数组,但是需要通过 数组名
	//5. 不能在定义 sum(double[] arr), 会认为重复定义
	public  double sum(double... args) {
		
		double totalSum = 0.0;
		for( int i = 0;  i < args.length; i++) {
			totalSum += args[i];
		}

		return totalSum;
	}
}

5.4注意事项和细节

1)可变参数的实参可以为0个或任意多个。
2)可变参数的实参可以为数组。
3)可变参数的本质就是数组.
4)可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
5)一个形参列表中只能出现一个可变参数
6)代码

//演示可变参数使用
public class VarArgsDetail
{
	public static void main(String[] args) {
		
		VarArgs va = new VarArgs();
		
		//细节1: 可变参数的实参可以为0个或任意多个
		va.sum();

		//可变参数的实参可以为数组
		double[] arr = {1,2,4};
		double res2 = va.sum(arr);
	}

	//可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
	public void m1(String name, String... args) {
		
	}
	//一个形参列表中只能出现一个可变参数
//	public void m2(int... args1 , String... args2) {
//		
//	}
	//演示可变参数使用
	//说明
	//1. double... 后面的三个小点,是规定
	//2. 这时 args 称为 可变形参
	//3. args 可变形参的本质就是数组
	//4. 实参可以传递数组,但是需要通过 数组名
	//5. 不能在定义 sum(double[] arr), 会认为重复定义
	public  double sum(double... args) {
		double totalSum = 0.0;
		for( int i = 0;  i < args.length; i++) {
			totalSum += args[i];
		}
		return totalSum;
	}
}

6创建Java自定义类步骤总结(OOP(oriented[面向] object[对象] programming[编程]))

**
6.1步骤

1)定义类,确定类名
2)编写类的属性
3)编写类的方法
4)创建对象,使用方法。

    ~~**自己先练习,后面有代码示例 具体问本人 本人QQ:825794519
    还有韩顺平老师的java原视频**~~  

Java编程 面向对象详讲
Java编程 面向对象详讲

import java.util.Scanner;
public class BoxExer
{
	public static void main(String[] args) {
	
		Scanner myScanner = new Scanner(System.in);
		Box box = new Box();
		System.out.println("长");
		box.len = myScanner.nextDouble();
		System.out.println("宽");
		box.width = myScanner.nextDouble();
		System.out.println("高");
		box.height = myScanner.nextDouble();

		System.out.println("体积=" + box.volume());
		
	}
}

/*
编程创建一个Box类,在其中定义三个属性表示一个立方体的长、宽和高,长宽高可以通过控制台输入。
定义一个方法获取立方体的体积(volume)。
创建一个对象,打印给定尺寸的立方体的体积
*/

class Box
{
	double len;
	double width;
	double height;

	public double volume() {
		return len * width * height;
	}
}

6.2景区门票案例

1)一个景区根据游人的年龄收取不同价格的门票。
2)请编写游人类,根据年龄段决定能够购买的门票价格并输出
3)规则:年龄>18 , 门票为20元,其它情况免费。
4)可以循环从控制台输入名字和年龄,打印门票收费情况, 如果名字输入 n ,则退出程序。
5)代码

import java.util.Scanner;

//游客
public class VisitorExer 
{
	public static void main(String[] args) {
	
		Scanner myScanner = new Scanner(System.in);
		//得到年龄
		do
		{
			//创建一个游客
			Visitor v = new Visitor();
			System.out.println("姓名:");
			v.name = myScanner.next();
			if( "n".equals(v.name)) {
				break;
			}
			System.out.println("年龄:");
			v.age = myScanner.nextInt();
			//计算
			v.ticketMoney();
			//显示
			v.showInfo();
		}while (true);		
	}
}

/*
1.一个景区根据游人的年龄收取不同价格的门票。
2.请编写游人类,根据年龄段决定能够购买的门票价格并输出
3.规则:年龄>18 , 门票为20元,其它情况免费。
4.可以循环从控制台输入名字和年龄,打印门票收费情况, 如果名字输入 n ,则退出程序。

*/

class Visitor
{
	String name; //名字
	int age; //年龄
	double payMoney;//应付
	//写一个方法,得到应付
	public void ticketMoney() {
		//规则:年龄>18 , 门票为20元,其它情况免费
		if(age > 18) {
			payMoney = 20;
		} 
	}
	//显示方法
	public void showInfo() {
		
		if(payMoney != 0) {
			System.out.println(name+ " 年龄是" + age + " 应付票价" + payMoney);
		} else {
			System.out.println(name+ " 年龄是" + age + " 免费");
		}
	}

}

7属性和局部变量作用域

7.1基本使用

1)面向对象中,变量作用域是非常重要知识点,相对来说不是特别好理解,请大家注意听,认真思考,要求深刻掌握变量作用域。

2)在java编程中,主要的变量就是属性(成员变量)和局部变量。A类:sum

3)我们说的局部变量一般是指在成员方法中定义的变量。【举例】

4)java中作用域的分类
全局变量:也就是属性,作用域为整个类体 A类:sum sub 等方法使用属性 【举例】
局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中!

5)全局变量可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才能使用,因为没有默认值。[举例]

7.2注意事项和细节使用

1)属性全局变量和局部变量可以重名,访问时遵循就近原则。

2)在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。[举例]

3)全局变量,存储在堆中。局部变量,存储在栈中,需要画一个示意图说明。【重要】

4)全局变量,生命周期较长,伴随着对象的创建而创建,伴随着对象的死亡而死亡。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而死亡。即在一次方法调用过程中。【每调用一次方法,就开一个方法栈,这个是由操作系统决定的】

5)作用域不同
全局变量:可以被本类使用,或其他类使用(通过对象调用)
局部变量:只能在本类中对应的方法中的作用域内使用

6)修饰符不同
全局变量/属性可以加修饰符
局部变量不可以加修饰符

7)特别说明: 如果我们在方法中,是new 对象,比如 Person p = new Person();
p在方法中, 对象数据空间在堆中…, 如果p 没有返回,则方法结束后,对象成为垃圾,被回收,如果返回给 其它方法,比如main , 则可以继续使用

import java.util.Scanner;

//游客
public class VarScopeTest 
{
	public static void main(String[] args) {
	}
}

class A {
	int num = 10;//属性
	int age;  //默认0

	public void m1() {
		int total = 30; //局部变量
		System.out.println(num);
	}
	public void m2() {
		//不能使用total
		System.out.println(num);
	}
	public void m3() {
		//全局变量可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才能使用,因为没有默认值
		System.out.println(age);
		int personNum = 9; //局部变量
		System.out.println(personNum);
	}
}

8构造方法

8.1看一个需求

我们来看一个需求:前面我们在创建人类的对象时,是先把一个对象创建好后,再给他的年龄和姓名属性赋值,如果现在我要求,在创建人类的对象时,就直接指定这个对象的年龄和姓名,该怎么做? 这时就可以使用构造方法/构造器。

8.2基本语法

[修饰符] 方法名(参数列表){
构造方法体
}

说明:
1)构造器的修饰符可以默认
2)构造器没有返回值
3)方法名 和类名字必须一样
4)参数列表 和 成员方法一样的规则
5)构造器的调用有系统JVM 来调用

8.3基本介绍

构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。它有几个特点:
1)方法名和类名相同
2)没有返回值
3)在创建一个类的新对象时,系统会自动的调用该类的构造方法完成对新对象的初始化。

8.4快速入门

现在我们就用构造方法来完成刚才提出的问题:在创建人类的对象时,就直接指定这个对象的年龄和姓名,该怎么做?
代码

import java.util.Scanner;

//游客
public class ConTest 
{
	public static void main(String[] args) {
		
		//传统写法
//		Person p1 = new Person();
//		p1.name = "jack";
//		p1.age = 20;

		//构造器
		Person p2 = new Person("tom", 30);
		System.out.println(p2.name + " " + p2.age);
	}
}

class Person
{
	String name;
	int age;

	//构造器
	public  Person(String pName, int pAge) {
		System.out.println("构造器被调用....");
		name = pName;
		age = pAge;
	}
}

8.5注意事项和使用细节
1)一个类可以定义多个不同的构造方法,构造方法重载
比如:我们可以再给Person类定义一个构造方法,用该方法来创建新对象的时候,只指定人名,不需要指定年龄。

2)构造方法名和类名相同

3)构造方法没有返回值

4)主要作用是完成对新对象的初始化, 并不是创建对象

5)在创建新对象时,系统自动的调用该类的构造方法

6)如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造方法),比如 Person (){}

7)一旦定义了自己的构造方法,默认的构造方法就覆盖了,就不能再使用默认的无参构造方法,除非显示的定义一下,即: Person(){};

8)代码

import java.util.Scanner;

//游客
public class ConDetail
{
	public static void main(String[] args) {

		new Dog("旺财");
		new Person();		
	}

}

//如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造方法),
//比如 Person (){}
class Person {

	//默认的一个无参构造器

	//一旦定义了自己的构造方法,默认的构造方法就覆盖了,
	//就不能再使用默认的无参构造方法,除非显示的定义一下
	public Person(String name) {
		
	}

	public Person() {}
}

class Dog {
	//一个类可以定义多个不同的构造方法,构造方法重载
	String name;
	int age;

	//第1个构造器
	public  Dog(String dName) {
		System.out.println("ok~~");
		name = dName;
		
	}

	//第2个构造器
	public Dog(String dName, int dAge) {
		name = dName;
		age = dAge;
	}

	
}

8.6对象创建的流程分析
看一个案例
class Person{
int age=90;
String name;
Person(String n,int a){
name=n;
age=a;
}}
Person p=new Person(“小倩”,20);

流程分析(面试题)
1)加载 Person 类 (Person.class), 只会加载一次
2)在堆中 开数据空间 , 得到一个地址
3)数据的初始化
(1) 默认初始化 age = 0, name = null
(2) 显示初始化 age = 90 , name = null
(3) 构造器初始化 age= 20 name = “小倩”
(4) 把 堆中的地址,返回给 p
(5) 使用

9this关键字

9.1看一段代码,引出this
Java编程 面向对象详讲
9.2什么是this
java虚拟机会给每个对象分配 this,代表当前对象。坦白的讲,要明白this 不是件容易的事,我给大家打一个比方。[上帝创世界小故事]

9.3深入理解this
为了进一步理解this,我们再看一个案例 (ThisTest.java)

public class ThisTest {

	public static void main(String[] args) {
		
		Dog dog = new Dog("旺财", 5);
		System.out.println("dog的地址(hashcode=)" + dog.hashCode());
		dog.showInfo(); 

		Dog dog2 = new Dog("来福", 2);
		System.out.println("dog2的地址(hashcode=)" + dog2.hashCode());
		dog.showInfo(); 
		//哪个对象调用,this就代表哪个对象
		dog.m1();
		dog2.m1();

	}
}

class Dog{

	public String name; // null
	public int age; //0

	//我们形参,本质就是 局部变量
	public Dog(String name, int  age){
		System.out.println(this.hashCode());
		this.name = name;
		this.age = age;
	}
	public void m1() {
		System.out.println(this.name);
		System.out.println("m1 this.hashCode=" + this.hashCode());
	}
	public void showInfo(){
		System.out.println(name + "\t" + age + "\t");
	}
}

对应的this理解的示意图
Java编程 面向对象详讲
9.4this的注意事项和使用细节
1)this关键字可以用来访问本类的属性、方法、构造器
2)this用于区分当前类的成员和局部变量
3)访问成员方法的语法:this.方法名(参数列表);
4)访问构造方法(构造器)语法:this(参数列表);
5)this不能在类定义的外部使用,只能在类定义的方法中使用
6)代码

public class ThisDetail {

	public static void main(String[] args) {
		
		
		AA a = new AA();
		a.m2();

		System.out.println(a.name); // smith

		AA a2 = new AA("king");
		System.out.println(a2.name); // king

		
	}
}

class AA {

	int age = 10;
	String name = "tom";

	public AA() { //构造器1
		//访问构造方法(构造器)语法:this(参数列表)
		this("smith"); // this 可以调用其它构造器, 需要在构造器内
	}

	public AA(String name) {
		//this用于区分当前类的成员和局部变量
		this.name = name;
	}

	public void m1() {
		//this关键字可以用来访问本类的属性、方法、构造器
		System.out.println(this.age);
	}

	public void hi() {
		System.out.println("hi");
	}
	public void m2() {
		System.out.println("m2()");
		//访问成员方法的语法:this.方法名(参数列表);
		this.hi(); // 可以访问 本类的 hi();
	}
}

本文地址:https://blog.csdn.net/huluo1/article/details/110449876