06面向对象(初级)类与对象、成员方法与传参机制、重载、可变参数、作用域、构造器、this

类与对象

张老太养了两只猫猫:一只名叫小白,今年三岁,白色。还有一只叫小花,今年一百岁,花色。请编写一个程序:
当用户输入小猫名字时,就显示:该猫的名字,年龄,颜色。
如果用户输入的小猫名错误,则显示:张老太没有这只猫猫
	单独变量来解决→不利于数据的管理(把一只猫的信息拆解了)
	第一只小猫的信息
	String cat1Name = "小白";
	int cat1Age = 3;
	String cat1Color = "白色";
	数组→1、体现不出来数据类型2、只能通过[下标]获取信息,造成变量名字和内容的对应关系不明确3不能体现猫的行为
	第一只猫和第二只猫的信息
	String[] cat1 = {"小白","3","白色"};

使用现有技术解决:
1单独的定义变量解决
2使用数组解决

现有技术解决的缺点:
不利于数据的管理
效率低→引出类与对象
java设计者引入类与对象(oop),根本原因就是现有的技术,不能完美的解决新的需求。
从类到对象,目前有几种说话:
1、创建一个对象 2、实例化一个对象 3、把类实例化

如何创建对象
	1先声明在创建
		Cat cat;
		cat = new Cat();
	2直接创建
	Cat cat = new Cat();

java创建对象的流程简单分析
	Person p = new Person();
	p.name = "jack";
	p.age = 10;
	1先加载person类信息(属性和方法信息,只会加载一次)
	2在堆中分配空间,进行默认初始化(看规则)
	3把地址赋给p,p就指向对象
	4进行指定初始化,比如p.name="jack";p.age=10;

类和对象的内存分配机制:
	java内存的结构分析
	1栈:一般存放基本数据类型(局部变量)
	2堆:存放对象(Cat cat,数组等)
	3方法区:常量池(常量,比如字符串),类加载信息

1、区别和联系
	1类是抽象的,概念的,代表一类事物,比如人类,猫类。。。即它是数据类型。
	2对象时具体的,实际的,代表一个具体事务
	3类是对象的模板,对象时类的一个个体
2、属性/成员变量
	1基本介绍从概念或叫法上看:成员变量=属性=field(成员变量是表示属性的)
	2属性是类的一个组成部分,一般是基本数据类型(对象,数组)。

3、注意事项和细节说明
	1属性的定义语法同变量
	2属性的定义类型可以为任意类型,包含基本类型或引用类型
	3属性如果不赋值,有默认值,规则和数组一致

练习题:
看下面一段代码,会输出什么:
	Person a = new Person();
	a.age = 10;
	a.name = "小明";
	Person b;
	b=a;
	System.out.println(b.name);//小明
	b.age = 200;
	b = null;
	System.out.println(a.age);//200
	System.out.println(b.age);//异常

成员方法

基本介绍:

在某些情况下,我们需要定义成员方法(简称方法)。比如人类:除了有一些属性外(年龄,名字)我们人类还有一些行为如:可以说话,走路。这时就要用成员方法从才能完成。

成员方法的好处

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

成员方法的定义

public 返回数据类型 方法名 (形参列表..){//方法体
	语句;
	return 返回值;
}
1、形参列表:标识成员输入cal(int n),getSum(int num1,int num2)
2、返回数据类型:表示成员方法输出,void表示没有返回值
3、方法主体:表示为了实现某一功能代码块
4、return 语句不是必须的

注意事项和使用细节

返回类型

1、一个方法最多一个返回值[如何返回多个结果:返回数组]
2、返回类型可以为人以类型,包含基本类型或引用类型(数组,对象)
3、如果方法要求有返回数据类型,则方法体中的执行语句必须为return 值;而且要求返回值类型必须和return的值类型一致或兼容
4、如果方法是void,则方法体重可以没有return语句,或者只写 return;

形参列表:

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

方法体:

里面写完成功能的具体语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但里面不能在定义方法。即:方法不能嵌套定义

方法细节调用说明

1、同一个类中的方法调用:直接调用即可。
2、跨类中的方法A类调用B类方法:需要通过对象名调用。如:对象名.方法名(参数)
3、特别说明一下:跨类的方法调用和方法的访问修饰符相关。

练习题

1编写类AA新方法:判断一个数是奇数还是偶数,返回boolean
2根据行列字符打印对应行数和列数的字符,比如行:4,列:4,字符#,则打印相应效果

成员方法传参机制

案例:

B类中编写一个方法test100,可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化。
B类中编写一个方法test200,可以接受一个Person(age,sal)对象,在方法中修改该对象属性,看看原来的对象是否变化。
	B b = new B();
	int[] arr = {1,2,3};
	b.test100(arr);
	System.out.println("MethodParameter01  arr数组");
	for(int i=0;i<arr.length;i++){
		System.out.print(arr[i]+" ");
	}
	System.out.println();
	
	//测试
	Person p = new Person();
	p.name = "jack";
	p.age = 10;
	b.test200(p);
	System.out.println("main的age="+p.age);//100

//B类中编写一个方法test200
//可以接受一个Person(age,sal)对象,在方法中修改该对象属性,看看原来的对象是否变化
class Person{
String name;
int age;
}
class B{
public void test200(Person p){
p.age = 100;//修改对象属性
}
//B类中编写一个方法test100
//可以接收一个数组,在方法中修改该数组,看看原来的数组是否变化
public void test100(int[] arr){
arr[0] = 100;

	System.out.println("test100  arr数组");
	for(int i=0;i<arr.length;i++){
		System.out.print(arr[i]+" ");
	}
	System.out.println();
}

}

结论:

引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参

方法递归调用

基本介绍:

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

递归重要规则

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

练习

1请使用递归的方式求出斐波那契数1,1,2,3,5,8,13...给你一个整数n,求出它的值是多少。

2猴子吃桃问题:有一堆桃子,猴子第一天吃了其中一半,并在多吃了一个!以后每天猴子都吃其中的一半,然后在多吃一个。当第10天时,想再吃时(即还没吃),发现只有一个桃子了。
问:最初一共有多少个桃子?

重载

基本介绍:

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

重载的好处:

1减轻了起名的麻烦
2减轻了记名的麻烦

注意事项和细节:

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

练习

类Methods中定义三个重在方法并调用。方法名为m。三个方法分别接受一个int参数、两个int参数、一个字符串参数。分别执行平方运算并输出结果,相乘并输出结果,输出字符串信息。在类的main()方法中分别调用参数区别调用三个方法。

class Methods{
	//1方法名 m
	//2新参int
	//3void
	public void m(int n){
		System.out.println(n+"的平方="+(n*n));
	}
		public void m(int n1,int n2){
		System.out.println(n1+"和"+n2+"相乘="+(n1*n2));
	}

		public void m(String str){
		System.out.println("传入的str=" + str);
	}
}

在Methods类,定义三个重载方法max(),第一个方法,返回两个int值中的最大值,第二个方法,返回两个double值中的最大值,第三个方法,返回三个double值中的最大值,并分别调用三个方法。
class Methods{
	public int max(int n1,int n2){
		return n1>n2 ? n1:n2;
	}
	public double max(double n1,double n2){
		return n1>n2 ? n1:n2;
	}
	public double max(double n1,double n2,double n3){
		double max1 = n1>n2 ? n1:n2;
		return max1>n3 ? max1:n3;
	}
}

可变参数

基本概念:

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

基本语法

访问修饰符 返回类型 方法名(数据类型... 形参名)

注意事项和使用细节

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

练习:

有三个方法,分别实现返回姓名和两门课成绩(总分),返回姓名和三门课成绩(总分),返回姓名和五门课成绩(总分)。封装成一个可变参数的方法 
class HspMethod{
	public String showScore(String name,double... scores){
		int sum = 0;
		for(int i=0;i<scores.length;i++){
			sum += scores[i];
		}
		return name+"的"+scores.length+"门课总成绩为"+sum;
	}
}

作用域

基本使用:

1在Java编程中,主要的变量就是属性(成员变量)和局部变量
2我们说的局部变量一般是指在成员方法中定义的变量
3java中作用域的分类
	全局变量:也就是属性,作用域为整个类体cat类:cry eat等方法使用属性
	局部变量:也就是除了属性之外的替他变量,作用域为定义它的代码块中
4全局变量不可以赋值,直接使用,因为有默认值,局部变量必须赋值后,才能使用,因为没有默认值。

注意事项和细节:

1属性和局部变量可以重名,访问时遵循就近原则。
2在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。
3属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。即在一次方法调用过程中。
4作用域范围不同
	全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
	局部变量:只能在本类中对应的方法中使用
5修饰符不同
	全局变量/属性可以加修饰符(public protected private...)
	局部变量不可以加修饰符

构造器

基本介绍:

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

注意事项和细节:

1一个类可以定义多个不同的构造器,即构造器重载如:我们可以再给Person类定义一个构造器,用来创建对象的时候,只指定人名,不需要指定年龄。
2构造器名和类名要相同
3构造器没有返回值
4构造器是完成对象的初始化,并不是创建对象
5在创建对象时,系统自动的调用该类的构造方法
6如果程序员没有定义构造方法,系统会自动给类生成一个默认无惨构造方法(也叫默认构造方法),比如Person(){},使用javap指令反编译看看
7一旦定义了自己的构造器,默认的构造器就覆盖了,就不能再使用默认的无参构造器,除非显示的定义一下。即Person(){}

练习:

在person类中添加两个构造器:
第一个无参构造器:利用构造器设置所有人的age属性初始值都为18
第二个带pName和pAge两个参数的构造器:使的每次创建Person对象的同时初始化对象的age属性值和name属性值。分别使用不同的构造器,创建对象。

this

什么是this:java虚拟机会给每个对象分配this,代表当前对象。

注意事项和细节使用:

1this关键字可以用来放文本类的属性、方法、构造器
2this用于区分当前类的属性和局部变量
3访问成员方法的语句:this.方法名(参数列表);
4访问构造器语法:this(参数列表);主义只能在构造器中使用
5this不能再类定义的外部使用,只能在类定义的方法中使用

练习:

定义person类,里面有name、age属性,并提供compareTo比较方法,用于判断是否和另一个人相等,提供测试类TestPerson用于测试,名字和年龄完全一样,就返回true,否则返回false

对象创建的流程分析

1加载类信息,只会加载一次
2在堆中分配空间
3完成对象初始化
	1默认初始化 age=0 name=null
	2显示初始化age=90,name=null
	3构造器初始化 age=20 name=小黑
4把对象在堆中的地址,赋值给p(p是对象名。也可以理解成是对象的引用)

作业:

1编写A01类,定义方法max,实现求某个double数组的最大值,并返回
2编写A02类,定义方法find,实现查找某字符串是否在数组中,并返回索引,如果找不到返回-1
3编写类Book,定义方法updatePrice,实现更改某本书的价格,具体:如果价格>150,则更改为150,如果价格>100,更改为100,否则不变
4编写类A03,实现数组的赋值功能aopyArr,输入旧数组,返回一个新数组,元素和旧数组一样
5定义一个圆类Circle,定义属性:半径,提供显示圆周长功能的方法,提供显示圆面积的方法
6创建一个Cale计算类,在其中定义2个变量表示两个操作数,定义四个方法实现求加减乘除(要求除数为0的时候,要提示)并创建两个对象,分别测试
7设计一个Dog类,有名字、颜色和年龄属性,定义输出方法show()显示其信息。并创建对象,进行测试、提示this属性
8下面程序输出结果为:10,9,10
	public class Test{
		int count=9;
		public void count1(){
			count = 10;
			System.out.println("count1="+count);
		}
		public void count2(){
			System.out.println("count1="+count++)
		}
		public static void main(String[] args){
			new Test().count1();//匿名对象使用后,就不能再次使用了
			Test().count1();
			t1.count2();
			t1.count2();
		}
	}

9定义Music类,里面有音乐名name、音乐时长times属性,并有播放play功能和返回本身属性信息的功能方法getInfo.
10下面代码的运行结果为:101,100,101,101
	class Demo{
		int i=100;
		public void m(){
			int j=i++;
			System.out.println("i="+i);
			System.out.println("j="+j);
		}
	}
	class Test{
		public static void main(String[] args){
			Demo d1 = new Demo();
			Demo d2 = d1;
			d2.m();
			System.out.println(d1.i);
			System.out.println(d2.i);
		}
	}
11在测试方法中,调用method方法,写出method方法的定义形式,调用语句为:System.out.println(method(method(10.0,20.0),100));
public double method(double d1,double d2){}
12创建一个Employee类,属性有(名字、性别、年龄、职位、薪水),提供三个构造方法,可以初始化(1)(名字、性别、年龄、职位、薪水)(2)(名字、性别、年龄)(3)(职位、薪水),要求充分使用构造器
13将对象作为参数传递给方法
	1定义一个Circle类,包含一个double型的radius属性代表圆的半径,一findArea()方法返回圆的面积。
	2定义一个类PassObject,在类中定义一个方法printAreas(),该方法的定义如下:public void printAreas(Circle c, int times)
	3在printAreas方法中打印出1到times之间的每个整数半径值,以及对应的面积。例如,times为5,则输出半径1,2,3,4,5,以及对应的圆的面积。
	4在main方法中调用printAreas()方法,调用完毕后输出当前半径值。运行结果如:
		Radius					Area
		1.0						3.1415926...
		2.0						12.566370...
		3.0						28.274333...
		4.0						50.265482...
		5.0						78.539816...
14有个人Tom设计它的成员变量.成员方法,可以电脑猜拳.电脑每次都会随机生成0,1,2。0表示石头1表示剪刀2表示布并要可以显示Tom的输赢次数(清单)
posted @ 2022-02-17 20:57  栗子一块两块  阅读(25)  评论(0)    收藏  举报