Java面向对象01——类与对象
大家好,我是白夜,今天和大家聊聊类与对象
一、初识面向对象(了解)
1.1、面向过程和面向对象
面向过程编程
C 语言就是面向过程编程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
面向对象编程
JAVA 是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
举个例子,比如洗衣服
面向过程:1.拿桶 2.把衣服放桶里 3.接水 4.放洗衣服 5.搓 6.再接水 7.把衣服拧干 8.晒衣服
面向对象:1.把衣服和洗衣粉放进洗衣机 2.打开洗衣机 3.把衣服拿出来晾干
在这里洗衣机就是一个对象,所以只要操作洗衣机所具备的功能,都要定义在对象中。
1.2、面向过程和面向对象的区别
面向过程:注重的是过程,在整个过程中所涉及的行为,就是功能。
面向对象:注重的是对象,也就是参与过程所涉及到的主体。是通过逻辑将一个个功能实现连接起来
二、类与对象
什么是类?
类是具备某些共同特征的实体的集合,是对所具有相同特征实体的抽象, 例如人类、车类、星球类,动物类, 猪类等
什么是对象?
对象是类的实例,简单的认为对象就是类中具体的个体。
用一个例子给你说明一下他们的关系:
比如“人类”就是一个类,那么具体的某个人“张三”就是“人类”这个类的对象,而“名字、年龄”等信息就是对象的属性,人的动作比如“吃饭、穿衣”等就是对象的方法
2.1、类的定义
语法:
class People{
//成员变量/字段/属性
//修饰符/数据类型/变量名
public String name ;
public String sex;
public int age;
//成员方法/行为
public void show(){
System.out.println("姓名:"+name+"性别:"+sex+"年龄:"+age);
}
}
要求:
- 类名,大驼峰,见名知意,不能以jdk中存在的类命名
- 成员变量名和方法名,小驼峰,见名知意
- 在类名、方法名、成员变量名上面写文档注释
2.2、类的实例化
用类类型创建对象的过程,称为类的实例化
我们已经知道通过class关键字来定义一个类了,而我们知道类只是相当于一个模板,所以我们要通过类来实例化对象,由类产生对象的过程叫做 实例化一个对象。
2.2.1、语法
class People{//类名大驼峰
//成员变量/字段/属性
public String name ;
public String sex;
public int age;
//成员方法/行为
public void show(){
System.out.println("姓名:"+name+"性别:"+sex+"年龄:"+age);
}
}
public class Test {
public static void main(String[] args) {
//我们通过 new 关键字来实例化一个对象
People p1 = new People();
//通过 new 关键字我们是可以实例化多个对象的
People p2 = new People();
People p3 = new People();
}
}
2.2.2、类在内存中的分析
每创建一个对象就会在内存中开辟一片空间,在栈上会开辟一个引用地址,会指向堆上的对象
p1 和p2 这些变量都是局部变量它们(对象)属于引用
注意:类里面的方法并不是是存在堆区的 ,方法本身是不占内存的,方法是存在方法区里的方法表中,在每个对象 new 好之后前面有几个字节存的就是方法表的地址,只有在调用这个方法时,会通过方法表的地址找到这个这个方法,然后在栈上为这个方法开辟栈帧。
2.2.3、访问类的成员
成员变量的访问:对象名 . 属性名
成员方法的访问:对象名 . 方法名
class People{
//成员变量/字段/属性
public String name ;
public String sex;
public int age;
//成员方法/行为
public void show(){
System.out.println("姓名:"+name+"性别:"+sex+"年龄:"+age);
}
}
public class Test {
public static void main(String[] args) {
People p1 = new People();
System.out.println(p1.name);
System.out.println(p1.sex);
System.out.println(p1.age);
p1.show();
}
}
注意:这里的成员变量并没有初始化,不同于局部变量不初始化会报错。成员变量不初始化是其类型对应的0值。
2.3、类的成员
2.3.1、初始化成员变量
我们把定义在类的内部,方法的外部的变量叫“字段”或者叫它成员变量有时候也叫它“属性"。这三种叫法并没有严格区分
public static void main(String[] args) {
People p1 = new People();
p1.name = "java";
p1.sex = "nan";
p1.age = 50;
p1.show();
}
}
还有一种就是在定义成员变量的时候赋值,但并不建议这样写,因为在实例化后还是能初始化,没必要多此一举。而且这个类是一个模板,把模板初始化也是不合适的。
class People{
//成员变量/字段/属性
public String name = "zhangsan" ;
public String sex = "lisi";
public int age = 22;
//成员方法/行为
public void show(){
System.out.println("姓名:"+name+"性别:"+sex+"年龄:"+age);
}
}
再来看一个代码,这个代码是什么意思呢?
public static void main(String[] args) {
//p1和p2都指向了这个对象
People p1 = new People();
People p2 = p1;
}
就是我们曾经讲过的方法,用于描述一个对象的行为.
class People{
//成员变量/字段/属性
public String name ;
public String sex;
public int age;
//成员方法/行为
public void show(){
System.out.println("姓名:"+name+"性别:"+sex+"年龄:"+age);
}
public void prt(){
System.out.println("爱java");
}
}
public class Test {
public static void main(String[] args) {
People p1 = new People();
p1.show();
p1.prt();
}
}
2.3、修饰符(了解)
对 Java 当中的,类,变量,方法,构造方法等等.....进行修饰,赋予被修饰内容特殊意义。
public(公共访问控制符):它表示公共的意思,被public修饰的类、接口、方法和变量等成员都可以被任何其他类或对象所访问。
private(私有访问控制符):它表示私有的意思,只有在定义该成员的类内部才能被访问。被private修饰的类、方法、变量或接口只能在自己的类中被调用,无法被同一个包内或者其他包中的其他类或对象所访问。
protected(保护访问控制符): 它表示受保护的意思。被protected修饰的类、方法、变量或者接口只能被相同包或其子类中的类或对象所访问。
static(静态修饰符):它可以用来修饰成员变量、成员方法和代码块。当一个变量或方法被声明为
static
时,它就是一个静态成员。final:有最终的、不可变更的意思,它可用于修饰类、变量和方法。用于表示它修饰的类、方法和变量不可改变。
native: 本地修饰符。指定此方法的方法体是用其他语言在程序外部编写的
abstract: 将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现。
transient(过度修饰符): 指定该变量是系统保留,暂无特别作用的临时性变量。
volatile: 指定该变量可以同时被几个线程控制和修改。
synchronize: 同步修饰符,在多个线程中,该修饰符用于在运行前,对他所属的方法加锁,以防止其他线程的访问,运行结束后解锁。
三、构造方法
3.1、构造方法的基本使用
构造方法是一种特殊方法, 使用关键字new实例化新对象时会被自动调用, 用于完成初始化操作 构造方法没有返回值,且方法名和类名是相同的 构造方法是用来构造对象的(实例化对象)
new 执行过程
1.为对象分配内存空间
2.调用合适的构造方法
语法:
-
构造方法的名字和类名完全一致(包括大小写完全一致)。
-
没有返回值类型(void也不行)。
-
构造方法方法体不能返回任何的值(即不能在方法体中return 值)。
-
其他的和普通方法类似 ,可以有修饰符(public、protected、private、默认),可以有形参列表。
-
构造方法必须有方法体。
-
构造方法不能有任何非访问性质的修饰符修饰,例如 static、final、synchronized、abstract等都不能修饰构造方法。
class People{
private String name ;
private int age;//普通成员变量
public static int cont;//静态成员变量
public People(){
System.out.println("这是一个不带有参数的构造方法");
}
}
public class Test {
public static void main(String[] args) {
People p = new People();
}
}
运行结果:
那么为什么我们前面示例化对象时为什么没有构造方法呢?
如果我们没有写构造方法,系统默认会有一个没有参数且没有任何内容的构造方法
特点:
- 每一个类中都至少有一个构造方法;
- 如果没有看到(显示的),那么存在一个隐式的无参数的构造方法;
- 如果一个类中有显示的构造方法,那么隐式的无参的构造方法就不存在了;
3.2、构造方法的重载
构造方法和方法一样是可以实现重载的, 由于需求不同,会创建多个构造方法
重载:
1.方法名要相同
2.参数列表不同(类型和个数)
3.返回值不做要求
class People{
private String name ;
private int age;//普通成员变量
public static int cont;//静态成员变量
public People(){
System.out.println("这是一个不带参的构造方法");
}
public People(String name){
System.out.println("这是一个带有一个参数的构造方法");
}
public People(String name,String sex){
System.out.println("这是一个带有两个参数的构造方法");
}
}
public class Test {
public static void main(String[] args) {
People p = new People();
People p1 = new People("张三");
People p2 = new People("李四","男");
}
}
四、匿名对象(了解)
概念:
匿名对象,就是创建的时候没有使用变量接收保存一个对象。但是匿名对象本质也是一个对象(具体的值)
作用:
可以节约资源,因为GC【垃圾回收器】会不定时回收匿名对象
使用场景
匿名对象一般用在:只需要使用一次的情况(如:调用一次非static修饰的普通方法、作为方法实参使用)
public class Main {
public static void main(String[] args) {
// 创建匿名对象并调用方法
new MyClass().doSomething();
// 在方法参数中使用匿名对象
printMessage(new Message("Hello, World!"));
}
static void printMessage(Message message) {
System.out.println(message.getText());
}
}
class MyClass {
void doSomething() {
System.out.println("Doing something...");
}
}
class Message {
private String text;
public Message(String text) {
this.text = text;
}
public String getText() {
return text;
}
}