【JavaSE】保姆级教程|1万字+10张图学会类与对象--建议收藏

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

Part1:引入

🤹‍♀️相信很多了解过C和Java/C++的一定对面向对象编程、面向对象编程、万物皆对象都早已耳闻了那到底什么是面向对象什么是面向过程呢接下来会举一个生动的例子让大家切身感受一下~

1.1人类的生活在面向对象化

🍳古人饿了vs现代人饿了

  • 古人饿了
    在这里插入图片描述
  • 现代人饿了
    在这里插入图片描述
    对比
  • 古代人古代人饿了他们要从打猎、生火、做饭再到吃要亲自把每一步都实现
//伪代码
public static void hunt(){
	hunt a woolf;
}
public static void makeFire(){
	...
}
cook(){
	食材woolf
	....
}
eat(){
	吃狼肉
}
public static void main(String[] args){
	hunt();//打猎
	makeFire();//生火
	cook();//做饭
	eat();//吃
}
  • 现代人饿了可以叫个外卖快递小哥接单厨师做菜快递小哥送单最后吃。每个人各司其职叫外卖的人不必知道外卖小哥是怎么送单也不必知道厨师是如何做菜同样外卖小哥不必知道年轻人是如何打的电话厨师又是如何做的菜…
//伪代码
//一抽取出3个类
class youngMan{
	public void call();
	public void eat();
}
class manForTakeaway{
	public void takeOrders();
	public void delivery();
}
class cook{
	public void cooking();
}		
class Demo{
	public static void main(String[] args){
		//二创建对象
		youngMan Ming = new youngMan();//创建明同学
		manForTakeaway Hua = new manFortakeaway();//创建出华这个外卖员
		cook Wang = new cook();//创建出厨师王

		//三使用对象
		Ming.call();
		Hua.takeOrders();
		Wang.cooking();
		Hua.delivery();
		Wang.cooking();
	}
}

🙇‍♀️总结

  • 面向过程对于一个问题分成几个步骤逐步解决。
  • 面向对象对于一个问题把问题中的每一个事物都看成是一个对象每个对象是唯一的有属于自己的功能。只需要发挥每一个对象自己的功能就能将问题解决。

1.2深入—万物皆对象

🤷‍♀️虽然根据上面这两个例子面向过程和面向对象可见一斑。但是你能说古人饿了这个问题完全是面向过程的嘛我其实认为不然。

  • 打猎古人使用弓箭但古人并不知道弓箭的箭与弓之间是如何受力如何发射的因为古人有射箭的属性而发射是弓箭的属性。所以古人和弓箭二者就是对象。
  • 生火古人有钻木取火的功能但是木头因为摩擦而与空气发生燃烧这是木头的性质与功能古人并不具备。所以这也能看成两个对象。

🦉综上万物其实皆对象~

1.2面向对象编程三大关键

  • 找对象
    • 🌙对象从哪里来对象由类而来。而类就是具体事物的抽象.所以找对象的关键就是把具体事物抽象为类.
      eg:上面”现代人饿了“例子中我们把具体的一个年轻人抽象为一类youngMan;把具体的外卖员抽象为一个类manForTakeaway;把具体的一个厨师抽象为一类cook。
  • 创建对象
  • 使用对象

Part2为什么会有"类与对象"?

当然通过上面所讲我们大概能参悟点对象&类的概念。我个人始终认为要理解好一个概念一个知识如果能明白它为什么存在存在的意义是什么则能更好去理解和运用

2.1现有技术无法满足需求

🙇‍♀️所有的技术最后还是和现实生活接轨的我们不可能只是简简单单的用编程来完成一些整数的运算求最大公约数诸如此类…而且只靠那些内置类型是完全不够的。比如你如何表示”人“这个类型又如何表示”动物“这个类型这些与现实生活相关一些复杂的问题仅仅靠int char Strin…是无法解决的也许能但是我想对开发人员也不友好吧如果一开始就有”人“/”动物“这个类型那得多方便~开发效率也会提高。
当然这也是我目前的一种理解也许每个人有自己的理解只要合理即可。

Part3初识类&对象

3.1类的构成

  • 字段/属性/成员变量
    • 普通成员变量
    • 静态成员变量被static修饰
  • 方法/行为
    • 普通成员方法
    • 静态成员方法
      在这里插入图片描述

3.2类的定义

  • 👩‍💼👨‍✈️👩‍⚖️👨‍🚒👩‍🏫👨‍⚕️👨‍🍳👩‍💻引子现实生活中有各个职位的人每一个具体职业的人或者说每一个具体的人抽象起来都有共同的属性如年龄性别和共同的行为如吃饭可以形成一个类–人类。
class Person{
	String name;
	int age;
	public void eat(){
		System.out.print(name+"eating");
	}
}
  • 字段/属性/成员变量定义在类的里面方法的外面。

注意类的命名采用大驼峰

3.3对象的实例化

  • 🧘‍♀️由类来创建对象我们叫做对象的实例化。
class Person{
	String name;
	int age;
	public void eat(){
		System.out.print(name+"eating");
	}
}
public class Demo{
	public static void main(){
	Person XiaoWang = new Person();//创建小王这个对象
	}
}
  • 类也可看作一种类型
  • 类是引用类型

3.4类&对象的关系

在这里插入图片描述

3.5成员变量的访问方式

  • 通过引用来访问成员变量/方法.person1是Person类变量引用类变量
class Person{
	String name;
	int age;
	public void eat(){
		System.out.print(name+"eating");
	}
}
public class Demo{
	public static void main(){
	Person person1 = new Person();
	//通过引用变量person1.来访问对象的属性
	person1.name="XiaoWang";
	person1.age=18;
	}
}

3.5.1:成员变量的默认值

在这里插入图片描述

3.6深入内存分析-对象在内存中如何存在⭐

3.6.1对象实例化过程图解

class Person{
	String name;
	int age;
	public void eat(){
		System.out.print(name+"eating");
	}
}
public class Demo{
	public static void main(){
	Person person1 = new Person();
	Person person2 = new Person();
	}
}

在这里插入图片描述

  • 首先Person person1的时候Person类就会被加载进JVM的方法区</font》
  • 其次new Person()的时候会在JVM的堆区中开辟一个空间用来存储对象。
  • 最后再把该对象空间在堆区上的地址赋给栈区上的引用变量类类型变量person1.

3.6.2访问成员变量过程图解

class Person{
	String name;
	int age;
	public void eat(){
		System.out.print(name+"eating");
	}
}
public class Demo{
	public static void main(){
	Person person1 = new Person();
	person1.name = "XiaoWang";
	}
}

在这里插入图片描述

  • 首先通过对象名.属性找到该引用所指向其在堆内存上的对象并访问其name属性
  • 由于name属性是引用类型则会先在方法区常量池开辟空间来存储该常量字符串
  • 最后将该方法区处理字符串地址赋值给属性即name

3.6.3总结

  • 对象存储在堆区上。
  • 普通成员变量依赖于对象存在即每一个对象都有自己的普通成员变量
  • 类其实也是一种类型类类型变量是引用类型变量存放的是所指向对象在堆区上的地址.
  • 类在计算机视角只是一个代码片段放在JVM的方法区。不占用栈和堆的空间。

3.7静态成员变量

3.7.1静态成员变量的定义

class Person{
	String name;
	int age;
	//定义一个静态变量
	static int count=0;
}
public class Demo{
	public static void main(){
	Person person1 = new Person();
	}
}

3.7.2内存分配

在这里插入图片描述

  • 当类被加载进内存时静态成员变量随着类一起进入方法区并常驻方法区
  • 静态成员变量是依赖于类而不依赖与对象的

3.7.3

class Person{
	String name;
	int age;
	//定义一个静态变量
	static int count=0;
}
public class Demo{
	public static void main(){
	Person person1 = new Person();
	Person person2 = new Person();
	//通过类直接访问静态变量不依赖于对象
	System.out.println(Person.count);
	//通过对象访问
	person1.count++;
	person2.count++;
	System.out.println(count);
	//2
	}
}
  • 无论有多少个对象静态变量只占一份空间。对象对静态变量的修改都是对这一份空间的修改。

Part4详谈成员方法

4.1成员方法定义

class Person{
	String name;
	int age;
	//如下定义的eat()是一个成员方法
	public void eat(){
		System.out.print(name+"eating");
	}
}
public class Demo{
	public static void main(){
	Person person1 = new Person();
	person1.name = "XiaoWang";
	}
}
  • public表示方法是公开的后期细讲

4.2成员方法内存分配问题

在这里插入图片描述

  • 一般认为其实无论是static方法还是non-static方法都是常驻内存空间的即当类被加载进JVM的时候方法信息方法的指令数据第一步干什么第二步干什么就被存储在了方法区中不过此时的方法处于。-----方法的静态表现
  • 但是我们经常听说某某方法在栈区开辟内存难道方法是存在与栈区上?no,no,no!我们通常所说方法在栈区开辟内存其实是为这个方法开辟空间或者说开辟方法的栈帧来存方法中的局部变量、形参,这些数据随着方法的调用而生成随着方法的调用结束而销毁-----函数栈帧的创建&销毁。------方法的动态表现

4.2.1实例方法

  • 实例方法其实就是普通成员方法non-static method)上面说到当类被加载进内存时类中所有方法信息都被保存进了方法区。普通成员方法也在方法区但是处于睡眠状态。你只有new对象来用对象去调用该实例方法该方法才会处于苏醒状态并且该实例方法会记住它们属于哪个对象~并指向此对象.实例方法运行过程中的形参、局部变量存储在栈区上。
    在这里插入图片描述
  • 综上能调用实例对象的前提是—有对象

4.2.3静态方法

  • 静态方法(static method)内存分配上也是随着类的加载永驻方法区。与实例对象不同的是它们不需要对象静态方法和类绑定不需要创建对象即可调用静态方法
  • 但是静态方法被调用时其局部变量&形参还是要在栈上开辟空间—方法栈帧。
  • 静态方法的意义让该类所有对象共享方法。

4.2.3总结

  • 实例方法&静态方法均常驻内存.它们都是在类被加载进内存时分配了空间—加载时机、分配内存相同
  • 方法是作为代码指令数据加载进JVM方法区不可写方法占多少内存与static无关。与属性不同不论有多少对象方法的代码都是一样的所以只需要一份内存来存放方法即可。
  • 实例方法运行起来表现不同原因有二1所传形参不同2对象成员变量的值不同属性不同
  • 方法运行时其临时变量、形参会在栈区开辟内存存储----方法的栈帧

Part5不容小觑的细节

5.1实例方法内不能定义静态变量

  • 💥错误代码
class Person{
	String name;
	int age;
	//如下定义的eat()是一个成员方法
	public void eat(){
		static int test;//erro!!!
		System.out.print(name+"eating");
	}
}
  • 首先实例方法是依赖对象没有对象调用就不会运行。而static变量是随着对象的加载而在内存方法区中储存。
  • 把static变量定义在实例方法中没有对象来调用方法使其运行是无法为static变量开辟内存空间的。
  • 最后你要明白的是实例方法属于对象你把static定义在实例方法内部就说明static变量属于对象这是不对的。因为static变量属于类。

5.2静态方法内不可定义静态变量

  • 💥错误代码
class Person{
	String name;
	int age;
	//如下定义的eat()是一个成员方法
	public static void eat(){
		static int test();//erro!!!
		System.out.print(name+"eating");
	}
}
  • 上面讲成员方法使已经很详细说了,static方法会保存进方法区但是保存的是代码。
  • 其次只有方法被调用才会在运行其内部变量才能开辟空间局部变量&形参
  • 把static变量定义在方法内部方法不被调用是不会未其开辟空间。这就导致类在加载进内存时无法储存static变量。故代码错误。

5.3静态方法内部不可调用实例方法

  • 💥错误代码
class Person{
	String name;
	int age;
	int test(){
	}
	//如下定义的eat()是一个静态成员方法
	public static void eat(){
		test();//erro!!!
		System.out.print(name+"eating");
	}
}
  • 实例方法永远依赖对象而存在。而静态方法依赖于类而存在。当用类去调用静态方法当然Ok但当静态方法中有实例方法此时没有对象是无法调用此方法的只有对象才可”唤醒“沉睡的实例方法啊

5.4总结

  • 判断此类型就要弄清楚先来后到
    类加载进内存。方法区存储类的信息、方法信息non-static&static方法的代码)、静态变量。–永远的第一步

  • 判断static修饰时可以想想如果没有对象只用类名调用行得通嘛


🏄‍♀️下期预告–详细讲解Java中最重要的语法–封装
🙆‍♀️专栏系列文章

🙈原创不易如果对你有所帮助还请三连+关注我是瑶瑶子持续输出优质文章

在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java