Java第六天

本文详细介绍了Java中的类与对象的概念及其区别和联系,包括类作为对象模板的角色和对象作为类实例的特性。此外,讲解了属性(成员变量)的定义、默认值以及内存分配机制,强调了栈、堆和方法区的作用。接着,讨论了成员方法的定义、调用流程和重载,以及方法的递归调用。还涵盖了构造方法在对象初始化中的重要性,以及this关键字的使用。最后,文章提到了作用域规则,特别是局部变量和全局变量(属性)的差异。
摘要由CSDN通过智能技术生成

Java第六天

类与对象

类与对象的区别和联系

public class Object01{
	public static void main(String[] args) {
		
		// String cat1Name = "小白";
		// int cat1Age = 3;
		// String cat1Color = "白色";

		// String cat2Name = "小花";
		// int cat2Age = 100;
		// String cat2Color = "花色";

		//实例化一只猫[创建一只猫对象]
		//1.new Cat() 创建一只猫
		//2.Cat cat1 = new Cat();把创建的猫赋给cat1
		//3.cat1 就是一个对象
		Cat cat1 = new Cat();
		cat1.name = "小白";
		cat1.age = 3;
		cat1.color = "白色";
		//创建第二只猫,并赋给cat2
		//cat2 也是一个对象
		Cat cat2 = new Cat();
		cat2.name = "小花";
		cat2.age = 100;
		cat2.color = "花色";

		System.out.println("第一只猫的信息:"+cat1.name+cat1.age+cat1.color);
		System.out.println("第二只猫的信息:"+cat2.name+cat2.age+cat2.color);
	}
}

class Cat{

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

属性/成员变量

基本介绍

  1. 从概念或叫法上看:成员变量=属性=field(字段)
  2. 属性是类的一个组成部分,一般是基本数据类型,也可以是引用类型(对象,数组)

注意事项和细节说明(PropertiesDetail.java)
  1. 属性的定义语法同变量,示例:访问修饰符 属性类型 属性名;
    访问修饰符:控制属性的访问范围
    有四种访问修饰符 public,proctected,默认,private
  2. 属性的定义类型可以为任意类型,包含基本类型和引用类型
  3. 属性如果不赋值,有默认值,规则和数组一致

类和对象的内存分配机制

Java内存的结构分析

  1. 栈:一般存放基本数据类型(局部变量)

  2. 堆:存放对象(Cat cat,数组等)

  3. 方法区:常量池(常量,比如字符串),类加载信息
    在这里插入图片描述

Java创建对象的流程简单分析

Person p = new Person();
p.name = "jack";
p.age = 10;
  1. 先加载Person类信息(属性和方法信息,只会加载一次)
  2. 在堆中分配空间,进行默认初始化
  3. 把地址赋给p,p就指向对象
  4. 进行指定初始化,如代码中的后俩行

成员方法

基本介绍
在某些情况下,我们需要定义成员方法(简称方法)。比如:人类,除了有一些属性(年龄,姓名)外,我们人类还有一些行为,比如说话、跑步…通过学习,还可以坐算术题

public class Method01{
	public static void main(String[] args) {
		
		Person p1 = new Person();
		p1.speak();//调用speak方法  		我是一个好人
		p1.cal01();//调用cal01方法		500500
		p1.cal02(9);//调用cal02方法		45
		p1.cal02(19);//调用cal02方法		190

		//调用getSum方法
		//把方法getSum返回的值赋给变量returnRes
		int returnRes = p1.getSum(10,20);
		System.out.println(returnRes);//30
	}
}

class Person{

	String name;
	int age;
	//方法
	//添加speak方法,输出”我是一个好人“
	//1.public:表示方法是公开
	//2.void:表示方法没有返回值
	//3.speak():speak是方法名,()形参列表
	//4.{}:方法体,可以写我们要执行的代码
	public void speak(){
		System.out.println("我是一个好人");
	}

	//添加cal01方法,可以技术从1加到1000的结果
	public void cal01(){
		int res = 0;
		for(int i = 1; i <= 1000; i++){
			res += i;
		}
		System.out.println(res);
	}

	//添加cal02方法,该方法可以接收一个数n,计算从1加到n的结果
	//1.(int n)形参列表,表示当前有一个形参n,可以接收用户输入
	public void cal02(int n){
		int res = 0;
		for(int i = 1; i <= n; i++){
			res += i;
		}
		System.out.println(res);
	}

	//添加getSum方法,可以计算俩个数的和
	//1.public 表示方法是公开的
	//2.int:表示方法执行后,返回一个int值
	//3.getSum方法名
	//4.(int num1, int num2)形参列表,2个形参,可以接收用户输入的俩个数
	//5.return res;表示把res的值返回
	public int getSum(int num1, int num2){
		int res = num1 + num2;
		return res;
	}
}

方法调用小结
  1. 当程序执行到方法时,就回开辟一个独立的空间(栈空间)
  2. 当方法执行完毕,或者执行到return语句时,就会返回
  3. 返回到调用方法的地方
  4. 返回后继续向下执行代码

成员方法的定义

访问修饰符 返回数据类型 方法名 (参数列表){//方法主体
​ 语句;
​ return 返回值;
}

  1. 参数列表:表示成员方法输入
  2. 返回数据类型:表示成员方法输出,void表示没有返回值
  3. 方法主体:表示为了实现某一功能代码块
  4. return语句表是必须的

注意事项和使用细节

访问修饰符(作用是控制方法使用的范围)
如果不写 则 默认访问

返回数据类型

  1. 一个方法最多有一个返回值
  2. 返回类型可以为任意类型,包含基本类型和引用类型
  3. 如果方法要求有返回数据类型,则方法主体中最后的执行语句必须为return值;而且要求返回值类型必须和return的值类型一致或者兼容
  4. 如果方法是void,则方法主体中可以没有return语句,或者只写return;
public class MethodDetail{
	public static void main(String[] args) {
		
		AA a = new AA();

		int[] res = a.getSumAndSub(10,15);

		System.out.println("和 = "+res[0]);
		System.out.println("差 = "+res[1]);
	}
}
//1、2
class AA{

	public int[] getSumAndSub(int n1, int n2){

		int[] resArr = new int[2];
		resArr[0] = n1 + n2;
		resArr[1] = n1 - n2;
		return resArr;
	}
}

//3
public double f1(){

	double d1 = 1.1*3;
	int n = 100;
	return n;//int -> double  是可以的
}

形参列表
  1. 一个方法可以有0个参数,也可以有很多个参数,中间用逗号隔开
  2. 参数类型可以为任意数据类型
  3. 调用带参数的方法时,一定对应着参数列表传入相同类型或兼容类型的参数
  4. 方法定义时的参数称为形式参数,简称形参;方法调用时的参数称为实际参数,简称实参,实参和形参的类型要一致或者兼容,个数、顺序必须一致

方法调用细节说明
  1. 同一类中的方法调用:直接调用即可。比如:print(参数);
  2. 跨类中的方法: A类调用B类方法:需要通过对象名调用
public class MethodDetail02{
	public static void main(String[] args) {
		A a = new A();
		a.sayOk();

		a.m1();
	}
}

class A{

	public void print(int n){
		System.out.println("print()方法被调用 n = " + n);
	}

	public void sayOk(){
		print(10);
		System.out.println("继续执行sayOk()...");
	}

	public void m1(){
		B b = new B();
		b.hi();
	}
}

class B{
	public void hi(){
		System.out.println("B类中的hi()被执行");
	}
}
方法递归调用

首先先通过俩个小案例来理解递归调用机制

案例一:

public class Recursion01{
	public static void main(String[] args) {
		T t1 = new T();
		t1.test(4);
	}
}

class T{
	public void test(int n ){
		if(n > 2){
			test(n - 1);
		}
		System.out.println("n = " + n);
	}
}

在这里插入图片描述

在这里插入图片描述

案例二:

public class Recursion01{
	public static void main(String[] args) {
		T t1 = new T();
		t1.factorial(5);//120
	}
}

class T{
	public int factorial(int n){
        if(n == 1){
            return 1;
        }else{
            return factorial(n - 1) * n;
        }
    }
}

分析截图

递归重要规则
  1. 执行一个方法时,就创建一个新的受保护的独立空间(栈空间)
  2. 方法的局部变量是独立的,不会相互影响
  3. 如果方法中使用的是引用类型变量,就会共享该引用类型的数据
  4. 递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError
  5. 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕

方法重载

基本介绍
java中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致
比如:System.out.println(); out是PrintStream类型
好处就是减轻了起名和记名的麻烦

public class OverLoad01{
	public static void main(String[] args) {
		
		MyCalculator mc = new MyCalculator();
		System.out.println(mc.calculate(1,2));//calculate(int n1, int n2)被调用  3
		System.out.println(mc.calculate(1,2.0));//calculate(int n1, double n2)被调用  3.0
		System.out.println(mc.calculate(1.0,2));//calculate(double n1, int n2)被调用  3.0
		System.out.println(mc.calculate(1,1,1));//calculate(int n1, int n2, int n3)被调用  3
	}
}

class MyCalculator{

	//下面的四个calculate方法构成了重载
	public int calculate(int n1, int n2){
		System.out.println("calculate(int n1, int n2)被调用");
		return n1 + n2;
	}
	public double calculate(int n1, double n2){
		System.out.println("calculate(int n1, double n2)被调用");
		return n1 + n2;
	}
	public double calculate(double n1, int n2){
		System.out.println("calculate(double n1, int n2)被调用");
		return n1 + n2;
	}
	public int calculate(int n1, int n2, int n3){
		System.out.println("calculate(int n1, int n2, int n3)被调用");
		return n1 + n2 + n3;
	}
}
注意事项和使用细节
  1. 方法名必须相同
  2. 形参猎豹必须不同(形参类型或个数或顺序,至少有一样不同,参数名无要求)
  3. 返回类型无要求

可变参数

基本概念
java允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法

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

}

public class VarParameter01{
	public static void main(String[] args) {
		
		method m = new method();
		int sum = m.sum(5,6,7,8,9);
		System.out.println(sum);//35
	}
}

class method{
	public int sum(int n1, int n2){
		return n1 + n2;
	}
	public int sum(int n1, int n2, int n3){
		return n1 + n2 + n3;
	}
	public int sum(int n1, int n2, int n3, int n4){
		return n1 + n2 + n3 + n4;
	}

	//上面三个方法名称相同,功能相同,参数个数不同 >> 使用可变参数优化

	//1.int... 表示接受的是可变参数,类型是int,既可接受多个int(0-多)
	//2.使用可变参数时,可以当做数组来使用 即nums 可以当做数组
	public int sum(int... nums){
		System.out.println("接收的参数个数= " + nums.length);
		int res = 0;
		for (int i = 0; i < nums.length; i++) {
			res += nums[i];
		}
		return res;
	}
}
注意事项和使用细节
  1. 可变参数的实参可以为0个
  2. 可变参数的实参可以为数组
  3. 可变参数的本质就是数组
  4. 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
  5. 一个形参列表中只能出现一个可变参数
public class VarParameterDetail{
	public static void main(String[] args) {
		int[] arr = {1,2,3};
		T t1 = new T();
		t1.f1(arr);//2.
	}
}

class T{
	public void f1(int... nums){
		System.out.println("长度 = " + nums.length);
	}

	//4.
	public void f2(String str, double... nums){

	}
}

作用域

  1. 在java编程中,主要变量就是属性(成员变量)和局部变量
  2. 局部变量一般是指在成员方法中定义的变量
  3. java中作用域的分类
    全局变量:也就是属性,作用域为整个类体
    局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中
  4. 全局变量可以不赋值,直接使用,因为有默认值,局部变量必须复制后,才能使用,因为没有默认值
public class VarScope{
	public static void main(String[] args) {
		Cat cat = new Cat();
		cat.hi();
		cat.cry();
		cat.eat();
	}
}

class Cat{

	//属性在定义时,可以直接赋值,也可以不赋值
	int age = 10;

	double weight;//默认值是0.0

	public void hi(){
		//局部变量必须赋值后才能使用
		int num;
		//System.out.println("num = " + num);//错误		
		String address = "猫";
		System.out.println("address = " + address);
		System.out.println("weight = " + weight);
	}
	{
		int num = 100;
	}
	public void cry(){
		int n = 10;
		String name = "jack";
		System.out.println("在cry中使用属性 age = " + age);
	}

	public void eat(){
		
		System.out.println("在eat中使用属性 age = " + age);
		//System.out.println("在eat中使用属性 name = " + name);//错误
		//System.out.println("在eat中使用属性 num = " + num);//错误
	}
}
注意事项和使用细节
  1. 属性和局部变量可以重名,访问时遵循就近原则
  2. 在同一个作用域中,比如在同一个成员方法中,俩个局部变量,不能重名
  3. 属性生命周期较长,伴随对象的创建而创建,伴随对象的死亡而死亡。
    局部变量生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而死亡。即在一次方法调用过程中
  4. 作用域范围不同
    全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
    局部变量:只能在本类中对应的方法使用
  5. 修饰符不同
    全局变量/属性:可以加修饰符
    局部变量不可以加修饰符
public class VarScopeDetail{
	public static void main(String[] args) {
		Person person = new Person();
		person.say();
		person.hi();

		T t = new T();
		t.test();
		t.test2(person);
	}
}

class T{
	//属性前面可以加修饰符
	public int age = 20;

	public void test(){
		Person p1 = new Person();
		System.out.println(p1.name);//jack
	}

	public void test2(Person p){
		System.out.println(p.name);//jack
	}
}
class Person{

	String name = "jack";

	public void say(){
		String name = "king";
		System.out.println("say() name = " + name);//king
	}

	public void hi(){
		String address = "北京";
		//String address = "上海";//错误
		address = "上海";
		System.out.println("address = " + address);//上海
	}
}

构造方法/构造器

基本介绍
构造方法又叫构造器,是类的一种特殊的方法,它的主要作用是完成对新对象的初始化

基本语法
[修饰符] 方法名(形参列表){
​ 方法体;
}

说明
  1. 构造器的修饰符可以默认
  2. 构造器没有返回值
  3. 方法名和类名字必须一样
  4. 参数列表和成员方法一样的规则
  5. 构造器的调用,由系统完成
public class Constructor01{
	public static void main(String[] args) {
	
		Person p1 = new Person("smith",80);
		
		System.out.println("p1的信息如下");
		System.out.println("p1对象name = " + p1.name);//smith
		System.out.println("p1的age = " + p1.age);//80

	}
}

class Person{
	String name;
	int age;
	public Person(String pName, int pAge){
		System.out.println("构造器被调用 完成对象的初始化");
		name = pName;
		age = pAge;
	}
}
注意事项和使用细节
  1. 一个类可以定义多个不同的构造器,即构造器重载
  2. 构造器是完成对象的初始化,并不是创建对象
  3. 如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫默认构造器),比如Person(){},使用javap指令反编译试试
  4. 一旦定义了自己的构造器,默认的构造器就被覆盖了,就不能再使用默认的无参构造器,除非显式的定义一下
public class ConstructorDetail{
	public static void main(String[] args) {
		
		Person p1 = new Person("king",40);
		Person p2 = new Person("tom");
	}
}

class Person{
	String name;
	int age;//默认0
	public Person(String pName, int pAge){
		name = pName;
		age = pAge;
	}

	public Person(String pName){
		name = pName;
		System.out.println(age);//0
	}

	Doge doge = new Doge();//使用的默认的无参构造器
	Doge doge1 = new Doge("jack");//使用有参数的构造器
}

class Doge{
	/*
		默认构造器
		Doge(){
	
		}
	*/
	public Doge(String dName){

	}
	Doge(){//显式的定义一下无参构造器

	}
}

this关键字

java虚拟机会给每个对象分配this,代表当前对象

public class This{
	public static void main(String[] args) {
		
		Dog dog1 = new Dog("大黄",8);
		dog1.info();//大黄  8  当前对象的hashCode是:366712642
		Dog dog2 = new Dog("小黑",5);
		dog2.info();//小黑  5  当前对象的hashCode是:1829164700

	}
}

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

	public void info(){
		
		System.out.println(this.name + "\t" + this.age + "\t"
		 + "当前对象的hashCode是:" + this.hashCode());

	}
}

简单来说,哪个对象调用,this就代表哪个对象


this的注意事项和使用细节

  1. this关键字可以用来访问本类的属性、方法、构造器
  2. this用于区分当前类的属性和局部变量
  3. 访问成员的语法:this.方法名(参数列表);
  4. 访问构造器语法:this(参数列表);注意只能在构造器中使用
  5. this不能再类定义的外部使用,只能在类定义的方法中使用
public class ThisDetail{
	public static void main(String[] args) {
		
		T t1 = new T();
		t1.f2();
		T t2 = new T();
	}
}

class T{

	//访问构造器语法:this(参数列表); 必须放置第一条语句
	public T(){
		//从这里去访问T(String name, int age)
		this("jack",100);
		
		System.out.println("T()构造器");

	}

	public T(String name, int age){

		System.out.println("T(String name, int age)构造器");
	}

	public void f1(){
		System.out.println("f1()方法被调用");
	}

	public void f2(){
		System.out.println("f2()方法被调用");
		//调用本类的f1
		//第一种方式
		f1();
		//第二种方式
		this.f1();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值