04章【面向对象(上)】

本文详细介绍了面向对象编程的基本概念,包括类与对象的关系、封装性、构造方法、静态关键字、单例设计模式以及对象数组的使用。通过实例和比较,帮助读者理解和掌握面向对象编程的核心思想和技术实践。
摘要由CSDN通过智能技术生成

面向对象基本概念

什么是面向对象:

  • 面向对象是一种编程思想。
  • 面向对象是一种思考问题的思维方式。
// 面向过程:以步骤为单位,通过一步一步完成具体事情
// 面向对象:以对象为单位,通过组合调用不同的对象完成某一事情

建立面向对象思维方式:

  • 先整体,再局部
  • 先抽象,再具体
  • 能做什么,再怎么做

如何学习面向对象:

  • 掌握一门面向对象语言的语法
  • 熟悉面向对象的设计原则
  • 熟悉面向对象设计模式

类与对象

类与对象的关系

  • 类表示一个共性的产物,是一个综合的特征,而对象,是一个个性的产物,是一个个体的特征。
  • 类由属性和方法组成:
    • 属性:就相当于一个个的特征
    • 方法:就相当于人的一个个的行为 例如:说话、吃饭、唱歌、睡觉

类和对象的定义格式

类的定义

在Java中可以使用以下的语句定义一个类:

class 类名称{
	属性名称;
	返回值类型 方法名称(){}
}
// 类可以没有名称和方法 => 空类

对象的定义

  • 一个类要想真正的进行操作,则必须依靠对象,对象的定义格式如下:
类名称 对象名称 = new 类名称() ;

按照以上的格式就可以产生对象了。

如果要想访问类中的属性或方法(方法的定义),则可以依靠以下的语法形式:

  • 访问类中的属性:
对象.属性 ;
  • 调用类中的方法:
对象.方法() ;

对象的声明和实例化

在java中对象声明有两种含义

声明对象:Horse horse= null; ;
// 表示声明了一个对象,但是此对象无法使用,horse没有具体的内存指向

实例化对象:horse= new Horse() ;
// 表示实例化了对象,可以使用

//通过对象调用方法:
horse.eat()

// 匿名对象调用方法:
// 一次性调用方法(调用后销毁)
new Horse().eat()

// 对象销毁
h = null 


对象与内存分析

  • new 关键字表示创建一个对象
  • new 关键字表示实例化对象
  • new 关键字表示申请内存空间
  • 注意:如果使用一个没有申请内存空间的对象,会报空指针异常:java.lang.NullPointerException

对象在内存中的结构:

Horse horse= null; 
horse = new Horse();

在这里插入图片描述

给对象的属性赋值:

horse.name =“小白”; 
horse.age = 4;

在这里插入图片描述

在内存中创建多个对象:

Horse horse1=null horse1 = new Horse()
Horse horse2=null horse2 = new Horse()

在这里插入图片描述

声明两个对象,一个实例化,一个没实例化

Horse horse1=null horse1 = new Horse()
Horse horse2=null

在这里插入图片描述

对象之间的赋值:

horse1.name=“小白” horse2=horse1
horse1.age=4 horse2.name=“小黑”

在这里插入图片描述

分别实例化两个对象:

Horse horse1=null horse1 = new Horse ()
Horse horse2=null horse2 = new Horse()

在这里插入图片描述

对象之间的赋值:

horse1.name=“小白” horse2=horse1
horse1.age=4 horse2.name=“黑黑”
horse2.name=“小黑”

在这里插入图片描述

类与对象小结

  • new关键字:表示向内存申请空间,也表示实例化一个对象,创建一个对象。
  • 一个对象在内存中的大小,由该对象的所有属性所占的内存大小的总和。引用类型变量在32位系统上占4个字节,在64位系统上占8个字节。加上而外的对象隐性数据所占的大小。
  • 相同的类型才可以赋值
  • 不同的引用,指向同一个对象,任何一个引用改变对象的值,其它引用都会反映出来。
  • 编程时要注意的问题,在确定不使用对象时,要尽早释放对象:引用=null
  • 当一个堆中的对象没有被任何引用变量所指向时,该对象会被JVM 的 GC 程序认为是垃圾对象,从而被回收

封装性

封装性的概念

  • 封装性是面向对象思想的三大特征之一。
  • 封装就是隐藏实现细节,仅对外提供访问接口。
  • 封装有:属性的封装、方法的封装、类的封装、组件的封装、模块化封装、系统级封装…

封装的好处

  • 模块化
  • 信息隐藏
  • 代码重用
  • 插件化易于调试
  • 具有安全性

封装缺点:

  • 会影响执行效率

封装之前:

class Person{
	String name;
	int age;
}

封装之后:

class Person{  
	//属性是成员变量
	private String name;
	private int age;
	//参数及方法内定义的变量是局部变量
	public void setName(String name){
		this.name = name;
	}
	public String getName(){
		return name;
	} 
}
  • 没有封装,外部可直接访问并修改
  • 访问权限修饰符:private:私有的,只能在本类中访问; public:公有的,可被外部的其他类访问
  • 在类外部访问私有属性,需要提供公有的方法来间接访问 getter and setter

成员变量和局部变量

  • 在类中的位置不同
    • 成员变量:在类中定义
    • 局部变量:在方法中定义或者方法的参数
  • 在内存中的位置不同
    • 成员变量:在堆内存(成员变量属于对象,对象进堆内存)
    • 局部变量:在栈内存(局部变量属于方法,方法进栈内存)
  • 生命周期不同
    • 成员变量:随着对象的创建而存在,随着对象的销毁而消失
    • 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
  • 初始化值不同
    • 成员变量:有默认初始化值,引用类型默认为null
    • 局部变量:没有默认初始化值,必须定义,赋值,然后才能使用
  • 注意:局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则

构造方法

什么是构造方法

  • 构造方法就是类构造对象时调用的方法,用于对象的初始化工 作
  • 构造方法是实例化一个类的对象时,也就是new 的时候,最先调用的方法。

构造方法的定义:

  • 构造方法是在类中定义的
  • 构造方法的定义格式:方法名称与类名称相同,无返回值类型的声明。

对象的实例化语法:

Dog dog = new Dog(); //new Dog后面有个括号,带括号表示调用了方法,此时调用的方法就是构造方法了

构造方法重载:

  • 无参构造方法:
public Dog(){}
  • 带一个参数的构造方法:
public Dog(String name){
	this.name = name;
}
  • 带多个参数的构造方法:
public Dog(String name,int age){
	this.name = name;
	this.age = age;
}

构造方法小结

  • 构造方法名称与类名相同,没有返回值声明(包括 void)
  • 构造方法用于初始化数据(属性)
  • 每一个类中都会有一个默认的无参的构造方法
  • 如果类中有显示的构造方法,那么默认构造方法将无效
  • 如果有显示的构造方法,还想保留默认构造方法,需要显示的写出来。
  • 构造方法可以有多个,但参数不一样,称为构造方法的重载
  • 在构造方法中调用另一个构造方法,使用this(…),该句代码必须在第一句
public Dog(String name){}

public Dog(String name, int age){
	this(name);
}
  • 构造方法之间的调用,必须要有出口。
  • 给对象初始化数据可以使用构造方法或setter方法,通常情况下,两者都会保留。
  • 一个好的编程习惯是要保留默认的构造方法。(为了方便一些框架代码使用反射来创建对象)
  • private Dog(){},构造方法私有化,当我们的需求是为了保正该类只有一个对象时。
    • 什么时候一个类只需要一个对象?比如,工具类(没有属性的类,只有行为)并且该工具对象被频繁使用。
    • 权衡只用一个对象与产生多个对象的内存使用,来确定该类是否要定义为只需要一个对象。

this关键字

在Java基础中,this关键字是一个最重要的概念。使用this关键字可以完成以下的操作:

  • 调用类中的属性
  • 调用类中的方法或构造方法
  • 表示当前对象:在方法调用过程中,哪个对象调用了方法,在方法内的this就表示谁

值传递与引用传递

示例一:值传递

public class ValueDemo{
	public static void main(String[] args){
			int x = 10;
			method(x) ;
			System.out.println(“x=+x) ;
		}
		public static void method(int mx){
			mx = 20;
	}
}

示例二:引用传递

public class RefDemo1{
	public static void main(String[] args){
		Duck d = new Duck();
		method(d) ;
		System.out.println(Duck age =+d.age) ;
	}
	public static void method(Duck duck){
		duck.age = 5;
	}
}
class Duck{
	int age = 2; //省略封装
}

示例三:String传递

public class RefDemo2{
	public static void main(String[] args){
		String name =“小飞”;
		method(name) ;
		System.out.println(“name=+name) ;
	}
	public static void method(String sname){
		sname =“小备”;
	}
}

示例四:String传递

public class RefDemo3{
	public static void main(String[] args){
		Person p = new Person();
		method(p) ;
		System.out.println(“person name=+p.name) ;
	}
	public static void method(Person p ){
		p.name =“备备”;
	}
}
class Person{
	String name =“飞飞”; //省略封装
}

对象的一对一关系

两个对象之间的一对一关系:
比如:
一个英雄(Hero)对一个兵器(Weapon)
代码如何表示?

Hero.setWeapon("name","country");

双向一对第一
单向一对第一


static关键字

  • 静态变量或方法不属于对象,但是依赖类
  • 静态变量是全局变量,生命周期从类被加载到程序结束
  • 静态变量只有一份(静态方法区中存储)
  • 静态变量是本类所有对象共享一份
  • 建议不要使用对象名去调用静态数据,直接使用类名调用
  • static修饰一个方法,则该方法属于类,不属于对象,直接使用类名调用
  • 静态方法不能访问非静态数据

static关键字的作用:

  • 使用static关键字修饰一个属性:声明为static的变量实质上就是全局变量
  • 使用static关键字修饰一个方法:通常,在一个类中定义一个方法为static,那就是说,无需本类的对象即可调用此方法
  • 使用static关键字修饰一个类(内部类)

class文件加载到内存的结构图:
在这里插入图片描述
声明为static的方法有以下几条限制:

  • 它们仅能调用其他的static 方法。
  • 它们只能访问static数据。
  • 它们不能以任何方式引用this 或super。

什么时候使用static?
所有对象共同的属性或方法,那么我们可以定义为静态的。


main方法分析

主方法:

public static void main(String[] args){
	//代码块
}

public:公有的,最大的访问权限
static:静态的,无需创建对象
void::表示没有返回值,无需向JVM返回结果
main:方法名,固定的方法名
String[] args:表示参数为字符串数组,可以在调用方法时传入参数


代码块

普通代码块

  • 直接写在方法中的代码块就是普通代码块
public class Demo1{
	public static void main(String []args){
	{// 普通代码块
		String info =“局部变量-1;
		System.out.println(info) ;
	}
	String info =	“局部变量-2;
	System.out.println(info) ;
	}
}

构造块是在类中定义的代码块

class Demo{
	{ // 构造块
	System.out.println("构造块") ;
	}
	public Demo(){
	System.out.println("构造方法。") ;
	}
}

在类中使用static声明的代码块称为静态代码块

class Demo{
	{
	System.out.println("构造块") ;
	}
	static{
	System.out.println("静态代码块") ;
	}
	public Demo(){
	System.out.println("构造方法。") ;
	}
};

同步代码块(多线程中讲解)


单例设计模式

单例设计模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  • 构造方法私有化
  • 声明一个本类对象
  • 给外部提供一个静态方法获取对象实例

两种实现方式:

  • 饿汉式:占用内存时间长,提高效率(生成类时创建)
  • 懒汉式:占用内存时间短,效率低(第一次调用时创建)

设计单例

项目中为什么使用单例(单例的好处)

  • 在设计一些工具类的时候(只有功能方法,没有属性)
  • 工具类可能会被频繁调用
  • 目的是为了节省重复创建对象所带来的内存消耗

能不能使用 构造方法私有化+静态方法 替代单例?


对象数组与管理

对象数组就是数组里的每个元素都是类的对象,赋值时先定义对象,然后将对象直接赋给数组。

Chicken[] cs= new Chicken[10];

使用对象数组实现多个Chicken的管理

对象数组案例

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值