面向对象--面向对象思想、封装、构造方法

引言

举例:手机有打电话,玩游戏,看电视功能。

Phone{
		Show();	//看电视
		Call();		//打电话
		Play();		//玩游戏
}

(1)面向过程
其实就是通过方法体现,并且在主方法中不断的调用方法。每次我需要什么功能,我就自定义一个什么方法,然后在main方法中去调用。若在其它类中也想调用这个方法,只能在其它类中再次单独自定义一个方法然后再去调用。这就叫面向过程。
(2)面向对象
创建多个类时,多个类都需要打电话功能时,不需要每次都把打电话功能的代码写出来。直接创建一个Phone类,该类里面封装了Phone的各种功能(方法)。然后其它类中若想要调用Call方法,不需要在本类中自定义方法,直接面向对象new Phone。然后在调用手机里面的方法new Phone().Call()。这就是面向对象。
面向对象是基于面向过程的。过程即自定义的方法,没有过程就没有对象。对象就是一个类(Phone),封装了各种方法。利用对象的方式让我们的代码复用性更高,所有的功能都封装到对象中,只要找到了这个对象,那么就可以访问(调用)对象中的功能。

1 面向过程和面向对象的区别

(1)面向过程是分析出解决问题所需要的步骤,然后用方法把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
(2)面向对象是构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在解决问题的步骤中的行为。

2 面向对象的好处

(1)面向对象是一种更加符合人们思考习惯的思想
(2)将复杂的问题简单化
(3)面向对象从最开始的执行者变成了指挥者
对第三条的理解:如我们去餐厅吃饭,我们直接面向服务员这个对象即可,我们只需要指挥服务员即可。点过菜后,服务员具有端茶,倒水,向厨师传达菜单,打扫卫生的功能。这些我们都不需要关系,我们只需要等待,指挥服务员完成这些就可以。
总结:
(1)先按照名词提取问题领域中的对象
(2)对对象进行描述,明确对象中应该具备的属性和功能
(3)通过new的方式去创建
(4)通过该对象去调用它已有的功能去做事情

3 案例

属性: 汽车颜色----color 轮胎数----number
行为(功能,方法): 开车
用代码进行描述:

/*
 * 汽车:
 * 属性:颜色,轮胎数
 * 行为:开车
 */
public class Car {
	//主方法是程序的主入口,这里不需要主方法,是因为本类不需要独立运行。
	//	成员变量
	String color;//颜色
	int number;//轮胎数
	//	成员方法
	public void run(){
		System.out.println("color:"+color+",number"+number);
	}
}
public class CarDemo {
//	本类需要独立运行,所以需要main方法
	public static void main(String[] args) {
		//	创建Car对象
		Car c = new Car();	//c是引用型变量
		//	调用该对象的功能和属性.格式:对象.对象成员
		c.color = "red";
		c.number = 4;
		c.run();
	}
}

堆栈运行图:
在这里插入图片描述
(1)main方法压栈
(2)new Car()创建一个Car对象,在堆中开辟一块空间,这块空间会自动生成一个内存首地址值。这个地址值赋值给引用型变量c(c = 0x0033)。c就指向(引用)这个对象,此时,对象中所有元素均未被赋值,但都有默认的初始化值。
(3)执行c.color = “red”;即对c所对用对象的color属性进行赋值。
(4)执行c.number = 4;即对c所对用对象的number属性进行赋值。
(5)执行c.run(); run方法进栈,对run方法中的引用地址c赋值(c = 0x0033),因此run方法也是指向Car这个区域。

4 类和对象

(1)类是一组具有相同(属性)和(行为)的对象的抽象。
类是对具体事物的抽象(描述)。它定义了属于该类的所有对象应该有哪些属性和方法。
事物的组成:属性(成员变量)、功能或行为(成员方法)。
(2)对象是该类事物创建的实例(实体),可以通过该对象调用具体的属性和行为。
每一个对象可以有自己的属性、方法,这意味着每一个对象都可以拥有自己的内部数据(这些数据通过对象的属性来表示)和行为(行为通过对象的方法来体现)。
关系:
类实例化产生对象,对象抽象化产生类。类是对象的模板,对象是类的实例,以类为模板可以创建不同的对象。

5 成员变量和局部变量的区别

(1)定义位置不同
成员变量定义在类中
局部变量定义在方法以及语句中
(2)内存中位置不同
成员变量存储在堆内存的对象中
局部变量存储在栈内存的方法中
(3)初始化值不同
成员变量在堆内存中,有默认的初始化值。(根据类型有不同的默认值:String–>null int–>0 double–>0.0 boolean–>false)
局部变量没有默认值,必须要声明并且进行初始化后才能够使用
(4)生命周期(存活时间)不同
成员变量是随着对象的出现而出现,随着对象的消失而消失
局部变量是随着方法的运行开始(进栈)而出现,随着方法的运行结束(出栈)而消失

6 创建对象

6.1 类的定义

属性:对应类中的成员变量
行为:对应类中的成员方法
定义类其实在定义类中的成员(成员变量和成员方法)。

6.2 对象的创建和使用

格式:

				类名 对象名 = new 类名();

一个类可以有多个对象,创建一个对象后会在堆中创建一块空间存放对象。
(new)是一个特殊的方法,用于创建一个类的实例。

7 匿名对象

创建对象不赋值给引用型变量名。即没有名字的对象。
匿名对象的使用场景:
当对象对方法进行调用时,而且只调用一次,就可以简化成匿名对象来进行书写。反之,当对象需要调用多次的成员(变量,方法)时,就不可以简化成匿名对象进行书写。
在这里插入图片描述
每使用一次匿名对象就会在堆中开辟一个地址,因此这种使用较少。如上图所示,一般也就在只会调用对象方法一次才会使用。第一行第二行代码由于没有引用,执行完就会当做垃圾处理。第三行第四行通过隐士this指向对象结果都是null和0。

8 基本数据类型和引用数据类型在进行参数传递时的区别

(1)基本数据类型传递的是值;
(2)引用数据类型传递的是地址;

public static void main(String[] args) {
//	基本数据类型调用
int x = 5;
basic_Data(x);
System.out.println("x="+x);
//x=5

//	引用数据类型调用
Demo d = new Demo();
d.x = 5;
reference_Data(d);
System.out.println("d.x="+d.x);
//d.x=10
}

//	基本数据类型作为形参传递
public static void basic_Data(int x){
	x=10;
}

//引用数据类型作为参数传递
public static void reference_Data(Demo d){
	d.x = 10;
}

在这里插入图片描述
在这里插入图片描述
(1)main方法进栈
(2)创建对象,在堆中开辟空间生成首地址值。赋值给引用数据变量d。此时d=0x002。在调用对象中成员变量x并指向堆中赋值x = 5.
(3)调用reference_Data方法,方法进栈。方法中传递对象名d中的地址值0x0022。因此该方法也指向堆中0x0022这个区域。执行到自定义方法中将堆中x = 5改为x = 10。
(4)此时打印d.x的结果就是打印堆中x = 10。

9 封装

是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
(1)方法就是一个最基本的封装体。(调用方法)
(2)类也是一个封装体。(可以让其他类去调用封装类的成员)
好处:
(1)提高了代码的复用性
(2)隐藏了实现的细节
(3)提高了安全性。
原则:
将不需要对外提供的内容都隐藏起来,这时我们就需要对外提供访问私有化成员变量的方式。
对于变量的操作:对封装的成员变量对外提供访问的方法有:
(1)赋值操作:set变量名()
(2)取值操作:get变量名()

快捷键:右键source----get and set方法
描述一个对象时,属性被私有化后,我们就需要对外提供操作访问的方法(set,get方法)来访问该属性。

10 构造方法

构造即创建。构造方法即创建对象就会生成一个方法。
作用:
主要用来在创建对象时初始化对象,即为对象成员变量赋初始值。
原理:
(1)在没有定义构造方法的情况下,编译器会在编译时添加一个默认的无参构造方法到class文件中,对对象进行初始化。
(2)一旦显式地定义了构造方法(包括有参和无参构造方法),那么默认构造方法就会自动消失,编译器就不会在自动生成构造方法,防止对象调用发生冲突(不知道调用哪个构造方法)。
(3)无参构造方法对对象初始化值仍为数据类型的默认值。有参构造方法对对象初始化会进行赋值。
(4)一个类中可以有多个构造方法,他们之间是以方法的重载来体现。

public class Person {
//	属性:对成员变量进行封装
	private int age;
	private String name;

	//	对成员变量年龄进行赋值
	public void setAge(int age){
		if(age>0 && age<150){
	//左边的this.age指的是全局变量,右边的是对象调用age传进的值
	//如果左边不用this,这时两边的age都是参数传进的age。
		this.age =age;
		}else{
//			System.out.println("您输入的年龄有误");
			//	抛出异常。此处不能使用输出语句。输出语句没有终止程序的功能,不符合逻辑。
			throw new RuntimeException("您的年龄数值"+age+"是有误的");
		}
	
	}
	//	对成员变量年龄进行取值操作
	public int getAge(){
		// 将成员变量的值返回到对象调用的方法中
		return age;
	}
//	对成员变量年龄进行赋值
	public void setName(String name){
		this.name = name;
	}
//	对成员变量年龄进行取值
	public String getName(){
		return name;
	}
//	行为
	public void speak(){
		System.out.println("name="+name+",age="+age);
	}
}
public static void main(String[] args) {
		//	创建对象
		Person per = new Person();
		//调用成员变量
//		per.name = "coco";
//		per.age = 18;
		
		per.setAge(18);
		int a = per.getAge();
		System.out.println(a);
		
		per.setName("coco");
		String n = per.getName();
		System.out.println(n);
		//调用成员方法
		per.speak();
	}

11 注意事项

(1)它没有返回值类型,也没有void。
(2)构造方法是特殊的成员方法,它与类同名。

public	类名(){
			return ;
		/*
		*所有方法都有return语句,
		*所有方法都可以被private所修饰
		*/	
} 

构造方法也是有return语句的,只用于结束语句。
(3)对象一创建就会调用构造方法,每个对象在生成时都必须执行构造方法,而且只能执行一次。
(4) 如果构造方法调用失败,那么对象也无法创建;
(5)构造方法可以被private所修饰,作用:其他类不能创建该对象。

12 构造方法与一般方法的区别:

(1)写法不一样
构造方法没有返回值类型,构造方法名与类名一致,首字母大写。
一般方法方法名首字母小写,
(2)运行上有差别
构造方法是对象在一创建的时候就会调用构造方法。
一般方法是在对象创建之后,才能够进行调用。
(3)方法调用次数
构造方法在对象创建时,只调用一次(因为初始化动作只做一次,而且要先执行),而一般方法可以调用多次

问题:写了有参的构造方法对对象的属性进行初始化之后,那么Set方法还要写吗?
要写,因为对象创建构造方法初始化之后,有可能还要对数据进行修改,我们就可以用set来完成。

public class Constructor {
	//成员变量
	String name;
	int age;
	
	//	无参构造方法
	public Constructor(){
		
	}
	// 有参构造方法
	public Constructor(String name){
		this.name = name;
	}
	
	//成员方法
	public void speak(){
		System.out.println("name="+name+",age="+age);
	}
}
public static void main(String[] args) {
		//创造对象,对象一创建,就会调用构造方法
		Constructor con = new Constructor();
		//调用对象的成员方法
		con.speak();
	}

版权声明:本文为weixin_43109549原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。