java 面向对象

一、创建对象的内存理解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iLu1w2ib-1603114652304)(Day06.assets/image-20201016103556834.png)]

创建对象的步骤
(1)将要创建对象的所属类型的字节码文件加载到方法区中
(2)在栈内存中创建一个Person类型的引用,将来用于存储在堆内存中对象的地址
(3)在堆内存中开辟内存空间,给成员变量分配内存
(4)给对象中成员变量进行默认初始化赋值
(5)将堆内存中开辟好内存的地址,赋值给对象名
说明:
(1)第一个使用某个类型的时候,会将该类型的字节码文件加载进方法区,第二次或者以后再进行时候的时候,不需要重复加载
(2)在创建对象的时候,默认隐含一个字节码地址,将来可以通过该对象找到对应自己的字节码对象
(3)那个对象调用方法,在方法的栈帧中,就默认隐含了该对象的地址
(4)只要看到new,就是在堆内存中新开辟一段内存空间。

两个引用指向同一个对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-akPvbnKp-1603114652306)(Day06.assets/image-20201016105535179.png)]

二、面向对象中的其他内容

成员变量和局部变量的比较

1、成员变量:定义在类中成员位置的变量,就是成员变量
2、局部变量:定义在类中方法中的局部位置的变量,就是局部变量
2、不同点:
代码层面:定义的位置不同
成员变量:类中方法外
局部变量:类中方法中
内存层面:空间不同
成员变量:属于对象,只有在创建完对象才能使用成员变量,和对象的内存位置相同,在堆内存中
局部变量:属于方法,在方法的栈帧中
内存层面:生命周期
成员变量:随着对象的创建而存在,随着对象的消失而消失。(栈内存中没有任何引用指向该对象的时候)
局部变量:随着方法的调用而存在,随着方法的调用结束而消失
初始化状态不同:
局部变量:没有默认的初始值,必须先进行初始化赋值,才能使用
成员变量:有默认的初始化值。
基本类型:
整数类型:0
小数类型:0.0
字符类型:‘\u0000’
布尔类型:false
引用类型:null


//成员变量和局部变量的比较
public class Demo_3 {
//	成员变量
	int a;
	double d;
	char c;
	boolean boo;
	String str;
	public static void main(String[] args) {
		Demo_3 de = new Demo_3();
		System.out.println(de.a);
		System.out.println(de.d);
		System.out.println(de.c);
		System.out.println(de.boo);
		System.out.println(de.str);
		
		
//		局部变量 ,没有进行初始化,就不能进行使用
		int b = 10 ;
		System.out.println(b);
	}
}

匿名对象

1、匿名对象:
没有名字的对象
2、格式:
new 类名();
3、匿名对象使用的场景
(1)只想调用一次此对象中的方法,这个时候就可以使用匿名对象来进行调用,
new Car().playFriend();
(2)匿名对象可以作为某个方法的实际参数。这种调用格式,虽然在主方法中,可以看做是一个匿名对象,但是在被调用的方法中,这个对象是有引用的对象,不是匿名对象
useCar(new Car());//匿名对象
(3)可以作为某个方法的返回值数据。进行返回。这种调用格式而言,虽然在被调用者方法中,可以看做一个匿名对象,但是在调用者看来,这个对象可能不是匿名对象
4、注意:
匿名对象是否可以给成员变量赋值。可以给成员变量赋值,但是没有意义,因为栈内存,没有任何一个引用保存匿名对象的地址,赋完值该对象就成为了垃圾对象,无法访问到的



public class Demo_4 {
	public static void main(String[] args) {
//		匿名对象
		Car c = new Car();//正常情况,有名字的对象,对象的名字c
		c.brand = "BMW";
		c.price = 500000;
//		c.run();
//		没有名字的对象:匿名对象
		new Car();
//		使用场景
//		(1)将来对于某个对象在创建之后,只想调用一次此对象中的方法,这个时候就可以使用匿名对象来进行调用,
		new Car().playFriend();
//		(2)匿名对象可以作为某个方法的实际参数。这种调用格式,虽然在主方法中,可以看做是一个匿名对象,但是在被调用的方法中,这个对象是有引用的对象,不是匿名对象
		useCar(new Car());//匿名对象
//		(3)可以作为某个方法的返回值数据。进行返回。这种调用格式而言,虽然在被调用者方法中,可以看做一个匿名对象,但是在调用者看来,这个对象可能不是匿名对象
		
		Car car = makeCar();
		car.brand = "保时捷";
		car.price = 400000;
		car.run();
//		注意事项
		new Car().brand = "奔驰";
		System.out.println(new Car().brand);
		
	}
	
	public static Car makeCar() {
//		Car c = new Car();
//		return c;
		return new Car();
	}
	
	
	public static void useCar(Car car) {//Car car = new Car();
		car.brand = "五菱神车";
		car.price = 10000;
		car.run();
	}
	
}

class Car{
//	属性
	String brand;
	double price;
//	行为
	public void run() {
		System.out.println(brand + " " + price + "跑的真快");
	}
	
	public void playFriend() {
		System.out.println("带上女朋友去兜风");
	}
}

三、封装

1、封装:隐藏事物的属性和实现细节,对外提供公共的访问方式。
2、封装的好处:
隐藏了事物的实现细节
提高了安全性
3、封装的原则
隐藏事物的属性
对外提供公共的方法访问

private关键字

1、private,私有的
2、可以修饰的内容
修饰成员变量
修饰成员方法
修饰构造方法
修饰内部类
3、修饰之后的效果
被private修饰的成员,外界就不能直接进行访问了,只能在本类中进行访问
4、private这个关键字,就是封装的一种体现
protected ,也是一种封装的体现



public class Demo_5 {
//	private关键字
	public static void main(String[] args) {
		Phone p = new Phone();
//		p.brand = "Apple";
		p.price = 12343;
		p.show();
//		p.call();
	}
}

class Phone {
//	private
	private String brand;//只能在本类中进行访问
	double price;

	public void show() {
		System.out.println(brand + " " + price);
	}
	
	private void call() {//被private修饰的方法,在其他类中也不能被调用
		System.out.println("打电话");
	}
}

Get和Set的方法

1、当属性被private修饰之后,外界就无法直接访问,所有就需要对外提供公共的访问方式,让外界可以间接的访问属性。对于当前类而言,就可以控制外界访问属性的方式。(让外界怎么访问,外界就只能怎么样去访问)
2、一般都是set方法,完成对成员变量的赋值,get方法完成对成员变量值得获取



public class Demo_6 {
	public static void main(String[] args) {
		Computer com = new Computer();
		
//		System.out.println(bom.brand);
		
		com.setPrice(19);
		System.out.println(com.getPrice());
	}
}

class Computer{
	
	private String brand ;
	private String color;
	
	private double price;
//	对外提供公共的访问方式
	
	public void setPrice(double d) {
//		控制外界访问price的权限
		/*if(d < 0) {
			System.out.println("你设置的值我这里不予许");
		}else {
			price = d;
		}*/
		price = d;
	}
	
	public double  getPrice() {
//		price += 1000;
		return price;
	}
	
	
	public void setBrand(String b) {//间接完成对brand的赋值
		brand = b;
	}
	
	public String getBrand() {//让外界间接的访问brand的值
		return brand;
	}
	
	public void setColor(String c) {
		color = c;
	}
	
	public String getColor() {
		return color;
	}
}

变量访问原则和this关键字

1、变量的访问原则:
变量的访问原则:(就近原则)
变量的定义(声明):带着数据类型的变量
变量的使用(访问):不带着数据类型变量
就近原则:在访问某个变量的时候,会先寻找最近的该变量的定义,如果找到了,就使用该变量,如果没有找到,才会向更远的位置去寻找该变量的定义
如果出现局部变量和成员变量同名的情况,一定是先使用局部位置定义的变量,如果没有,才会使用成员位置定义的变量
2、this关键字
表示当前类型当前对象的引用
那个对象调用this所在的方法,this代表的就是那个对象
如果出现了局部变量和成员变量同名的情况,还想区分出成员变量和局部变量。就可以使用this关键字,被加上this.的变量一定是成员变量


public class Demo_7 {
	public static void main(String[] args) {
//		 变量的访问原则:(就近原则)
//		就近原则:在访问某个变量的时候,会先寻找最近的该变量的定义,如果找到了,就使用该变量,如果没有找到,才会向更远的位置去寻找该变量的定义
//		如果出现局部变量和成员变量同名的情况,一定是先使用局部位置定义的变量,如果没有,才会使用成员位置定义的变量
//		变量的定义(声明):带着数据类型的变量
//		变量的使用(访问):不带着数据类型变量
		Star s = new Star();
		s.setName("王宝强");
		s.setAge(200);
	}
}

class Star {
	private String name = "刘德华";
	private int age = 100;
	String n = "张益达";
//	提供get,set方法的,对外提供公共的访问方式,让外界间接去访问该类中的属性
	public void setName(String name) {
		this.name = name;
	}
	/*public void setName(String n) {
		System.out.println("StarName " + name);
		System.out.println("n " + n);
		name = n;
		System.out.println("StarName " + name);
	}*/

	public String getName() {
		return name;
	}

	public void setAge(int age) {
		System.out.println(age); // 200
//		如果出现了局部变量和成员变量同名的情况,还想区分出成员变量和局部变量。
//		就可以使用this关键字,被加上this.的变量一定是成员变量
		this.age = age;
		System.out.println(this.age);//100
	}

	public int getAge() {
		return age;
	}
}

构造方法概述

1、构造方法:构造函数,构造器
2、作用:就是给成员变量进行赋值,构造方法在创建对象的时候,会自动调用,等对象创建完之后,对象中的成员变量就已经有具体的值了。
3、构造方法的格式
修饰符 方法名称(参数列表){
方法体;
}
4、说明
(1)构造方法方法名称,必须和类名保持一致,大小写都一样
(2)构造方法没有返回值类型的,连void都没有
(3)构造方法没有return语句的。如果你要写一个return,就写一个return;
5、注意:
(1)构造方法,不需要手动的调用,会创建对象的时候自动的调用一次
(2)对象本身不能调用构造方法
(3)每创建一个对象,只能调用一次构造方法
(4)构造方法只能在创建对象的时候,对成员变量赋值一次,不能再次通过构造方法完成对成员变量值得修改。


public class Demo {
	public static void main(String[] args) {
//		构造方法
		Animal an = new Animal("老鼠");
		System.out.println(an.getName());
		an.setAge(12);
		an.setAge(122);
		an.setAge(142);
		
//		an.Animal("mouse");对象本身不能调用构造方法
		
		
		Animal an1 = new Animal("cat",23);
//		构造方法只能在创建对象的时候,对成员变量赋值一次,不能再次通过构造方法完成对成员变量值得修改。
//		如果想对该对象的成员变量值进行修改,那就是用set方法即可
		System.out.println(an1.getName());
		System.out.println(an1.getAge());
	}
}

class Animal{
	private String name;
	private int age;
//	构造方法
	public Animal() {
//		没有参数的构造
		name = "狮子";
		
	}
	
	public Animal(String name) {//在创建对象的时候,传入具体的数据
		this.name = name;
		return;
	}
	
	public Animal(String name,int age) {
		this.name = name;
		this.age = age;
	}
//	get  set方法
	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;
	}
}

构造方法的注意事项

1、构造方法是可以有参数的,也可以没有参数
没有参数的空参构造:外界无法传入具体的数据,只能成员变量赋固定值
有参数的构造方法:外界在去创建对象的时候,可以指定具体的成员变量的值,使用构造方法完成参数的传递,进行对成员变量的赋值的过程。
2、如果在类中没有定义任何的构造方法,那么系统会默认提供一个空参构造。
如果在类中定义了任何的一个构造方法,那么系统都不会再提供空参构造了。
如果在类中,即使不去使用空参构造,一旦定义有参构造的时候,建议也要写上空参构造。
3、构造方法的重载
在同一个类中,方法名相同,参数列表不同,与返回值类型无关。
构造方法的重载,方法名都是和类名一致,【参数列表的不同】,返回值类型没有



public class Demo_8 {
	public static void main(String[] args) {
//		构造方法的注意事项
		Animal an = new Animal("ffs");
		System.out.println(an.getName());
	}
}

class Animal{
	private String name;
	private int age;
//	构造方法
	public Animal() {
		name = "pig";
		
	}
	
	public Animal(String name) {//在创建对象的时候,传入具体的数据
		this.name = name;
		return;
	}
	
	public Animal(String name,int age) {
		this.name = name;
		this.age = age;
	}
//	get  set方法
	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;
	}
}

创建对象三个初始化的过程

1、创建对象的过程中,有三个初始化的过程
默认的初始化
显示初始化
构造初始化
2、三者的顺序
通过直接对成员变量的赋值,发现打印的结果是显示初始化的结果,因此显示初始化在默认初始化之后
通过在构造方法中对成员变量赋值,发现答应的结果是构造初始中赋值后的结果,因此构造初始化在显示初始化之后
顺序:默认初始化,显示初始化,构造初始化
3、图示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SGE69Q4q-1603114652308)(Day06.assets/image-20201016163844472.png)]

(1)将对象的字节码文件加载到方法区
(2)在占内存中声明一个Studeng类型的引用stu。将来用来存储在堆内存中开辟的内存空间的地址
(3)在堆内存中开辟内存空间,成成员变量分配内存
(4)给成员变量进行默认初始化赋值
(5)给成员变量进行显示初始化赋值
(6)给成员变量进行构造初始化赋值
(7)将对象的内存地址,赋值给栈内存中声明的引用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值