6-面向对象编程

现有技术解决问题的缺点分析

  • 不利于数据的管理;
  • 效率低

==> 引出新的知识点 类与对象

引入类与对象(OOP)编程 根本原因就是现有技术不能完美的解决新的需求

例如:

张老太养了两只猫猫:一只名字叫小白,今年 3 岁,白色。还有一只叫小花,今年 100 岁,花色。请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示张老太没有这只猫猫。

类与对象

一个程序就是一个世界,有很多事物(对象[属性][行为])
在这里插入图片描述

代码示例

public class Object01{
	public static void main(String[] args){
		// 创建实例cat1
		Cat cat1 = new Cat();

		// 赋值
		cat1.name = "小白";
		cat1.age = 3;
		cat1.color = "白色";

		// 创建实例 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;
}

image-20230208163242911

类和对象的区别与联系

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

对象的创建

1、先声明再创建

Cat cat;  //先声明对象cat
cat = new Cat();  //创建

2、直接创建

Cat cat = new Cat();

访问属性

基本语法:对象名.属性名;

例如

cat.name;
cat.age;
cat.color;

对象在内存中存在形式

// 创建实例
Cat cat = new Cat();

// 赋值
cat.name = "小白";
cat.age = 12;
cat.color = "白色"

在这里插入图片描述

在执行Cat cat = new Cat();时,会将类的信息加载到方法区

image-20230208164630051

属性与成员变量

属性也被称之为成员变量或称为field

属性是类的一个组成部分,一般是基本数据类型,也可是引用类型(对象,数组)

注意事项

  • 属性定义方法:访问修饰符 属性类型 属性名;
  • 属性的定义类型可以为任意类型,包含基本类型或引用类型;
  • 属性如果不赋值,有默认值,规则和数组一致;

代码示例

public class Object02{
	public static void main(String[] args){
		// 创建实例
		// p1是对象名(对象引用)
		// new Person() 创建的对象空间(数据) 才是真正的对象
		Person p1 = new Person();

		// 对象的属性默认值
		System.out.println("当前信息:" + p1.age + ", " + p1.name + ", " + p1.sal + ", " + p1.isPass);

	}
}


// 定义类
class Person{
	// 属性
	int age;
	String name;
	double sal;
	boolean isPass;
}

image-20230208171305096

类与对象的内存分配机制

思考题

Person p1 = new Person();
p1.age = 10;
p1.name = "小明";
Person p2 = p1;
System.out.println(p2.age);

问:p2.age输出的内容是什么?

完整代码

public class Object03{
	public static void main(String[] args){
		Person p1 = new Person();
		p1.age = 10;
		p1.name = "小明";

		Person p2 = p1;
		
		System.out.println(p2.age);
	}
}


class Person{
	int age;
	String name;
}

image-20230208172859300

内存图

image-20230208173551565

Java内存的结构分析

  • 栈:一般存放基本数据类型(局部变量)
  • 堆:存放对象(Cat cat,数组等)
  • 方法区:常量池(常量,例如字符串),类加载信息

示例2

public class Object04{
	public static void main(String[] args){
		Person a = new Person();
		a.age = 10;
		a.name = "小名";
		Person b;
		b = a;
		System.out.println(b.name);
		b.age = 20;
		b = null;
		System.out.println(a.age);
		System.out.println(b.age);
	}
}


// 定义类
class Person{
	String name;
	int age;
}

image-20230208211939351

成员方法

成员方法也称之为方法,例如:人类除了有一些属性外,还有行为(吃饭、说话、跑步等等),这时就要用成员方法才能完成

快速入门

  • 添加speak成员方法,输出:小白学安全
  • 添加cal01成员方法,可以计算1+…+100的结果
  • 添加cal02成员方法,该方法可以接收一个数n,计算从1+…+n的结果
  • 添加getSun成员方法,可以计算两个数的和

代码部分

public class Method01{
	public static void main(String[] args){
		Person p1 = new Person();
		p1.speak();
		p1.cal01();
		p1.cal02(100);

		int returnSum = p1.getSum(10,20);
		System.out.println("第四个问题的结果为:" + returnSum);
	}
}


class Person{
	String name;
	int age;

	// 1.speak方法
	public void speak(){
		System.out.println("第一个问题为:" + "小白学安全");
	}

	// 2.计算1到100
	public void cal01(){
		int sum = 0;
		for(int i = 1;i < 101;i++){
			sum += i;
		}
		System.out.println("第二个问题的结果为:" + sum);
	}

	// 3.计算1到指定数的结果
	public void cal02(int n){
		int sum = 0;
		for(int i = 1;i <= n; i++){
			sum += i;
		}
		System.out.println("第三个问题,1到" + n + "的计算结果为:" + sum);
	}

	// 4.计算两个数的和
	public int getSum(int n, int m){
		int sum = n + m;
		return sum;
	}
}	 

image-20230209102704114

方法调用机制-原理图

image-20230209105109041

在这里插入图片描述

小结:
1、 当程序执行到方法时,就会开辟一个独立的空间(栈空间);

2、当方法执行完毕,或者执行到return语句时,就会返回到调用的地方;

3、返回后,继续执行方法后面的代码;

4、当main方法(栈)执行完毕后,整个程序退出;

成员方法必要性

需求:遍历一个数组,输出数组中的各个元素值

之前方法:

public class Method02{
	public static void main(String[] args){
		int[][] map = {{0,0,1},{1,1,1},{1,1,3}};

		// 遍历
		for(int i = 0; i < map.length; i++){
			for(int j = 0; j < map[i].length; j++){
				System.out.print(map[i][j] + " ");
			}
			System.out.println()
;		}
	} 
}

image-20230209110127761

再次遍历呢????

使用成员方法:

public class Method02{
	public static void main(String[] args){
		int[][] map = {{0,0,1},{1,1,1},{1,1,3}};
		MyTools tool = new MyTools();
		tool.printArr(map);
		tool.printArr(map);
		tool.printArr(map);
	} 
}

class MyTools{
	public void printArr(int[][] map){
		System.out.println("=================");
		// 遍历
		for(int i = 0; i < map.length; i++){
			for(int j = 0; j < map[i].length; j++){
				System.out.print(map[i][j] + "\t");
			}
			System.out.println();		
		}
	}
}

image-20230209110722371

成员方法的好处

1、提高代码的复用性;

2、可以将实现的细节封装起来,然后供其他用户来调用;

成员方法的定义

语法:

访问修饰符 返回的数据类型 方法名(形参列表[,...]){
	代码块;
	[return 返回值];
}

说明:
1、形参列表:表示成员方法输入,例如:cal(int n);

2、返回的数据类型:表示成员方法的输出类型,void表示没有返回值;

3、代码块:表示为了实现某个功能的代码块;

4、return 返回值 不是必须的;

5、访问修饰符的作用是控制方法的使用范围,共有四种;如果不写则默认为private;

Tips:方法是写在类里面的

注意事项与使用细节

关于返回的数据类型

  • 一个方法最多有一个返回值;
  • 返回的数据类型可以为任意类型,包含基本数据类型和引用数据类型(数组,对象);
  • 如果成员方法要求有返回数据类型,则代码块中最后的执行语句必须为return 值;而且要求返回的数据类型必须和return 的值类型一致或兼容;
  • 如果返回的数据类型是void,则代码块中可以没有return语句,或者只写return;
  • 成员方法名应遵循驼峰命名法,例如:getSum();

关于形参列表

  • 一个成员方法可以有0个参数,也可以有多个参数,中间用逗号隔开,例如:getSum(),getSum(int num1, int num2);
  • 形参列表可以为任意类型,包含基本数据类型和引用数据类型(数组、对象),例如:printArr(int[][] map);
  • 调用带参数的成员方法时,一定对应着参数列表传入相同类型或兼容类型的参数;
  • 成员方法定义时的参数称之为形式参数,简称形参;成员方法调用时的传入参数称之为实际参数,简称实参;实参与形惨的类型要一致或兼容、个数、顺序必须一致;

关于成员方法中的代码块

里面的代码块可以写完成功能的具体语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但是成员方法中的代码块不能再定义成员方法,即成员方法不能嵌套调用;

关于成员方法的调用

  • 同一类中的成员方法可以直接调用;
  • 跨类中的成员方法A类调用B类中的成员方法,需要通过对象名调用,例如:对象名.成员方法(参数);
  • 跨类的成员方法调用与成员方法的访问修饰符有关;

克隆对象

public class Method03{
   public static void main(String[] args){
   	Person p = new Person();
   	p.name = "小白学安全";
   	p.age = 100;

   	MyTools myTools = new MyTools();
   	Person p2 = myTools.copyPerson(p);
   	System.out.println(p2.age);
   	System.out.println(p2.name);
   }
} 


class Person{
   String name;
   int age;
}


class MyTools{
   public Person copyPerson(Person p){
   	Person p2 = new Person();
   	p2.name = p.name;
   	p2.age = p.age;

   	return p2;
   }
}

image-20230209204848668

类定义

image-20230209113629698

方法递归调用

递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂问题,同时可以让代码变得简洁。

示例

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

image-20230209214206377

递归执行机制

image-20230209214301122

递归传递调用

public class Recursion02{
	public static void main(String[] args){
		T t1 = new T();
		int res = t1.factorial(5);
		System.out.println(res);
	}
}


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

image-20230210204352249

递归重要规则

1、执行一个方法时,就创建一个新的受保护的独立空间(栈空间);

2、方法的局部变量是独立的,不会互相影响,比如n变量;

3、如果方法中使用的是引用类型变量(数组、对象),就会共享该引用类型的数据;

4、递归必须向退出递归的条件逼近,否则就是无限递归,出现死循环;

5、当一个方法执行完毕或者遇到return时,就会返回。遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法 也就执行完毕。

递归斐波那契

问题

使用递归的方法求出斐波那契数1,1,2,3,5,8,13…
给一个整数n,求出它的值为多少

代码

public class RecursionExercose01 {
	public static void main(String[] args){
		T t1 = new T();
		System.out.println(t1.fbnq(7));
	}
}



class T{

	public int fbnq(int n ){
		if( n >= 1){
			if(n == 1 || n == 2){
				return 1;
			}else{
				return fbnq(n-1) + fbnq(n-2);
			}
		}else{
			return -1;
		}
	}
}

运行

在这里插入图片描述

猴子吃桃

问题

有一堆桃子,猴子第一天吃其中的一半,并再多吃一个
以后猴子每天都吃其中的一半,然后再多吃一个。那么到第十天时,想再吃桃子时,发现只有一个桃子了。
问:最初一共多少个桃子

代码

public class MonkeyEatPeach{
	public static void main(String[] args) {
		T t2 = new T();
		System.out.println(t2.peach(1));
	}
}

class T{
	public int peach(int day){
		// 第十天只有一个桃
		if(day == 10){
			return 1; 
		}else{
			return (peach(day + 1) + 1) * 2;
		}
	}
}

运行

在这里插入图片描述

  • 27
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值