面向对象基础 (通俗易懂)

1. 面向对象思想概述

面向过程: 当需要实现一个功能的时候,每一个具体的步骤都要亲历亲为,详细处理每一个细节
面向对象: 当需要事项一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我做事

public class Demo01PrintArray{
    
    
	public static void main(String[] args){
    
    
		int[] array = {
    
     10, 20, 30, 40};
		/*
		// 要求打印格式为:[10, 20, 30, 40]
		// 使用面向过程,每一个步骤细节都要亲历亲为
		
		System.out.print("[");
		for(int i = 0; i < array.length; i++){
			if(i == array.length - 1){
				System.out.println(array[i] + "]");
			}else{
				System.out.print(array[i] + ", ");
			}
			
		}
		*/
		System.out.println("======================");
		
		//直接调用方法,直接按要求输出
		System.out.println(Arrays.toString(array));
	}
}

2. 类的定义

现实世界的一类事物:

       属性:事物的状态信息
       行为:事物能够做什么

Java中用class描述事物也是如此:

       成员变量:对应事物的属性
       成员方法:对应事物的行为

3. 对象的创建及其使用

3.1 举例一

要求: 定义一个类,用来模拟学生事物。其中就有两个组成部分。
分析:
属性(是什么)
       姓名、年龄
行为(能做什么)
       吃饭、睡觉、学习

对应到Java的类当中
成员变量(属性):

String name eat(){}//姓名
int age; //年龄

成员方法(行为):

public void eat(){}//吃饭
public void sleep(){}//睡觉
public void study(){}//学习

注意事项:
1.成员变量是直接定义在类当中的,在方法外边
2.成员方法不要写static关键字
3.普通的方法是带有static的,成员方法的特点是没有static的。
IDEA快捷操作:sout = System.out.println();

public class Student{
    
    
	//成员变量(属性):
	String name;//姓名
	int age;//年龄
	
	//成员方法
	public void eat(){
    
    
		System.out.println("吃饭");
	}
	public void sleep(){
    
    
		System.out.println("睡觉");
	}
	
	public void study(){
    
    
		System.out.println("学习");
	}
}
public class Demo02Student{
    
    
	public static void main(String[] args){
    
    
		// 1.导包
		// 我需要使用的Student类,和我自己Demo02Student位于同一个包下,所以省略导包语句不写。
		
		// 2. 创建,格式
		// 类名称 对象名 = new 类名称();
		
		
		Student stu = new Student();
		
		// 3. 使用其中的成员变量格式
		// 对象名.成员变量名
		System.out.println(stu.name);//null
		System.out.println(stu.age);//0
		System.out.println("======================================");
		
		//改变对象当中的成员白能量,格式
		// 将右侧的字符串,赋值交给stu对象当中的name成员变量
		stu.name = "秀妍";
		stu.age = 22;
		System.out.println(stu.name);//秀妍
		System.out.println(stu.age);// 18
		
		//4. 使用对象的成员方法。格式:
		//对象名.成员方法名()
		System.out.println("===================================");
		stu.eat();
		stu.sleep();
		stu.study();
	}

3.2 举例二

定义一个类,用来模拟手机事物
属性:品牌、价格、颜色
行为:打电话、发短信
对应到类当中,
成员变量(属性)
    String brand; //品牌
    String price; //价格
    String color; //颜色
成员方法(行为)
    public void call(String who){}//打电话
    public void sendMessage(){}// 群发短信

代码如下:

public class Phone{
    
    
	//成员变量
	String brand;//品牌
	double price;//价格
	String color;//颜色
	
	//成员方法
	public void call(String who){
    
    
		System.out.println("给"+ who + "打电话");
	}
	public void sendMessage(){
    
    
		System.out.println("群发短信");
	}
}
public class Demo01PhoneOne{
    
    
	public static void main(String[] args){
    
    
		Phone one = new Phone();
		one.brand = "小米";
		one.price = 2999.0;
		one.color = "蓝色";
		System.out.println(one.brand);
		System.out.println(one.price);
		System.out.println(one.color);
		System.out.println("================================");
		
		one.call("小明");
		one.sendMessage();
	}
}

4. 对象内存图

4.1 一个对象的内存图

当创建一个对象的时候内存当中发生了哪些事那,来一张图展示:
在这里插入图片描述
程序在内存当中的执行过程:
(1)new的东西全都在堆当中,把成员变量放入堆当中,然后给他们附上默认值,对于一个对象来说,它的成员方法保存的其实是一个地址值,当创建对象的时候,call()、sendMessage()地址值将会保存在堆当中,指向右边的方法区。创建对象的地址值放到了Phone one当中。
(2)成员变量是根据栈当中的地址值找到堆当中的变量 ,然后进行修改。
(3)成员方法是两步走的,根据栈中的地址值找到堆 ,在根据堆里的成员方法的地址值在(4)方法区当中找到成员方法,call方法要想运行也是要进栈的,进栈也叫做压栈,后来的方法会把先来的方法压在底下。call方法已经用完之后就出栈。方法调用完之后,最后main也完事了。所有的内存都已经消失不见,程序停了下来。

小提示: 对象名称其实就是一个变量名称
shift + F6可以统一的重命名。
数组、对象、类的话传递的是地址值
array.fori = for(int i = 0 ; i < array.length; i++)

4.2 两个对象使用同一个方法的内存图

这个内存的大致流程与一个对象的内存图类似

在这里插入图片描述

4.3 两个引用指向同一个对象的内存图

one这个对象的地址值给了two,相当于两个对象名称拥有相同的地址值,所以指向同一个对象。
在这里插入图片描述

5. 使用对象类型作为方法的参数

直接上图:

在这里插入图片描述

6. 使用对象类型作为方法的返回值

直接上图:在这里插入图片描述

7. 成员变量和局部变量的区别

  1. 定义的位置不一样【重点】
    局部变量:在方法的内部
    成员变量:在方法的外部,直接写在类当中
  2. 作用范围不一样【重点】
    局部变量:只有方法当中才可以使用,出了方法就不能再用
    成员变量:整个类全都可以通用
  3. 默认值不一样【重点】
    局部变量:没有默认值,如果要想使用,必须手动进行赋值
    成员变量:如果没有赋值,会有默认值,规则和数组一样
  4. 内存的位置不一样【了解】
    局部变量:位于栈内存
    成员变量:位于堆内存
  5. 生命周期不一样【了解】
    局部变量:随着方法进栈而诞生,随着方法出栈而消失
    成员变量:随着对象创建而诞生,对着对象被垃圾回收而消失

8. 面向对象三大特性之封装

面向对象三大特性:封装、继承、多态

封装性在Java当中的体现:
1.方法就是一种封装
2.关键字private也是一种封装

封装就是将一些细节信息隐藏起来,对于外界不可见

9. private关键字的作用及使用

一旦使用了private进行修饰,那么本类当中仍然可以随意访问
但是,超出了本类范围之外就不能再直接访问了。

间接访问叫setXxx或者是getXxxx命名规则。
对于Getter来说,不能有参数,返回值类型和成员变量对应,
对于Setter来说,不能有返回值,参数类型和成员变量对应

9.1 举例一

问题描述:定义Person的年龄是,无法阻止不合理的数值被设置进来,
解决方案:用private关键字将需要保护的成员变量进行修饰
具体代码如下:

public class Person{
    
    
	String name; // 姓名
	private int age; // 年龄
	public void show(){
    
    
		System.out.println("我叫:" + name + ",年龄:" + age);
	}
	public void setAge(int num){
    
    
		if(num < 100 && num >= 9){
    
    
			age = num;
		}else{
    
    
			System.out.println("数据不合理!");
		}
		
	}
	public int getAge(){
    
    
		return age;
	}
}
public class Demo03Person{
    
    
	public static void main(String[] args){
    
    
		Person person = new Person();
		person.show();
		
		person.name = "赵丽颖";
		person.setAge(23);
		person.show();
	}
}

9.2 举例二

注意: 对于基本类型的boolean值,Getter方法一定要写成isXxx的形式,而setXxx规则不变

/*
对于基本类型的boolean值,Getter方法一定要写成isXxx的形式,而setXxx规则不变
*/
public class Students{
    
    
	private String name;
	private int age;
	private boolean male;
	
	public void setName(String str){
    
    
		name = str;
	}
	public String getName(){
    
    
		return name;
	} 
	public void setAge(int num){
    
    
		age = num ;
	}
	public int getAge(){
    
    
		return age ;
	}
	public void setMale(boolean a){
    
    
		male = a;
	}
	public boolean isMale(){
    
    
		return male;
	} 
}

public class Demo04Students{
    
    
	public static void main(String[] args){
    
    
		Students stu = new Students();
		stu.setName("鹿晗");
		stu.setAge(20);
		stu.setMale(true);
		
		System.out.println("姓名," + stu.getName());
		System.out.println("年龄," + stu.getAge());
		System.out.println("是不是纯爷们," + stu.isMale());
		
	}
}

10. this关键字的使用

当方法的局部变量和类的成员变量重名的时候,根据“就近原则”,优先使用局部变量
如果需要访问本类当中的成员变量,需要使用格式this.成员变量名
目的: 解决方法的局部变量和类的成员变量重名问题

通过谁调用的方法谁就是this
比如下面栗子中,person调用的方法sayHello,所以person就是this,他们的地址值是一致的。

public class Persons{
    
    
	String name;
	
	//参数name是对方的名字
	//成员变量name是自己的名字
	public void sayHello(String name){
    
    
		System.out.println(name + ",你好。我是" + this.name);
		
		System.out.println("这是this的地址值:" + this);//地址值,验证这句话 “通过谁调用的方法谁就是this”
	} 
}
public class Demo05Person{
    
    
	public static void main(String[] args){
    
    
		Persons person = new Persons();
		person.name = "王健林";
		person.sayHello("王思聪");
		System.out.println("这时person的地址值:" + person);//地址值,验证这句话 “通过谁调用的方法谁就是this”
	}
}

11. 构造方法

构建方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是再调用构造方法。这个跟c语言中的结构体类似。
格式:

public 类名称(参数类型 参数名称){
    
    
	方法体
}

注意事项:
1.构造方法的名称必须和所在的类名称完全一样,就连大小写也要一样
2.构造方法不要写返回值类型,连void都不写
3.构造方法不能return一个具体的返回值
4.如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,没有参数方法体什么事情都不做public Student(){}
5.一旦编写了至少一个构造方法,那么编译器将不在赠送
6.构造方法也是可以进行重载的。
重载:方法名称相同,参数列表不相同。

举个栗子:

public class Studentss{
    
    
	//成员变量
	private String name;
	private int age;
	
	//无参数的构造方法
	public Studentss(){
    
    
		System.out.println("无参构造方法执行了");
	}
	
	//全参数的构造方法
	public Studentss(String name,int age){
    
    
		System.out.println("全参构造方法执行了");
		this.name = name;
		this.age = age;
	}
	//Getter 、Setter
	public void setName(String a){
    
    
		name = a;
		
	}
	public String getName(){
    
    
		return name;
	}
	public void setAge(int b){
    
    
		age = b;
	}
	public int getAge(){
    
    
		return age;
	}
}
public class Demo07Student{
    
    
	public static void main(String[] args){
    
    
		Studentss stu1 = new Studentss();
		
		System.out.println("=================");
		
		/*
		只是创建对象的时候方便我们把那些现成的数据,通过参数的形式,设置进来,
		省去多次调用setXxx的方法。当区修改对象内容的时候,setXxx方法还是有用的。
		*/
		
		Studentss stu2 = new Studentss("赵丽颖",20);
		
		System.out.println("姓名:" + stu2.getName() + " 年龄:" + stu2.getAge());
		
		
		//如果需要改变对象当中成员变量数据内容,仍然还需要使用setXxxx
		
		stu2.setAge(21);//改变年龄
		System.out.println("姓名:" + stu2.getName() + " 年龄:" + stu2.getAge());
	}
}

11.1 定义一个标准的类

一个标准的类通常要拥有下面四个组成部分:
1.所有的成员变量都要使用private关键字修饰
2.为每一个成员变量编写一对Getter/Setter
3.编写一个无参数的构造方法
4.编写一个全参数的构造方法

这样标准的类也叫做Java Bean

可以让IDEA自动生成这四个部分:
code->Generate->Getter and Setter 按住shift键两个都选上。
code->Generate->Constructor(构造器)->Select None(因为时没有参数的)
code->Generate->Constructor(构造器)->Select None(全参数的)

举个栗子:

public class Studentsss{
    
    
	private String name;
	private int age;
	public Studentsss(){
    
    
		
	}
	public Studentsss(String name,int age){
    
    
		this.name = name;
		this.age = age;
	}

	public void setName(String name){
    
    
		this.name = name;
	}
	public String getName(){
    
    
		return name;
	}
	
	public void setAge(int age){
    
    
		this.age = age;
	}
	public int getAge(){
    
    
		return age;
	}
	
}
public class Demo08Student{
    
    
	public static void main(String[] args){
    
    
		Studentsss stu = new Studentsss("赵丽颖",20);
		System.out.println("姓名:" + stu.getName() + "  年龄:" + stu.getAge() );
		stu.setAge(22);
		System.out.println("姓名:" + stu.getName() + "  年龄:" + stu.getAge() );
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_46818279/article/details/108041946