java 面向对象的基础

本文深入讲解了Java中的面向对象编程,包括类与对象的概念,如何定义类及创建对象,对象内存的结构,以及static关键字的作用。此外,还详细阐述了封装、继承、多态这三大面向对象特征,抽象类和接口的使用,以及Java接口的新特性默认方法、静态方法和私有方法。内容涵盖了对象的生命周期、内存管理以及方法调用的原理,帮助读者深入理解Java面向对象编程的核心概念。
摘要由CSDN通过智能技术生成

面向对象的基础

1.类和对象

  • 类:类别,用来区分一类事物
    • 如:电脑,汽车,人,动物,等等…
  • 每类事物都具有: 属性和行为
  • 属性: 就是该事物所具有的特征(成员变量)
  • 行为:就是该事物可以做的事(实现的具体功能)

定义类的思路

就是定义一个类的属性和行为

public class Student {

	private String name ;		// 定义了name属性,并且的私有的
    private int 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 void show() {
        System.out.println() ; 
    }

}

使用类:

  • 格式:类名 对象名 = new 类名();
  • 对象:就是某一个事物的具体体现
  • 类和对象的关系:一对多
  • 万物皆对象
//创建对象
Student s1 = new Student() ;
Student s2 = new Student() ;
...
    
// 调用方法
s1.show();
s2.show();
  • 什么是面向对象?
    • 面向对象:指挥对象去做事,不考虑怎么做,只负责指挥
    • 代码的体现:创建对象并调用方法,不考虑功能是如何实现的,只负责调用
  • 方法的调用:方法需要什么参数就传什么参数,方法的返回值类型是什么,就用什么类型的变量来接收
Student s1 = new Student() ;

// public int getNumber(int number)
int number = s1.getNumber(12) ;

2.对象内存

2.1 一个对象的内存图

JVM(java虚拟机)的内存结构:

  • 栈(java虚拟机栈):每调用一个方法时,都需要将方法加载到栈内存中
    • 局部变量:在方法上或者方法内声明(定义)的变量,随着方法的入栈而创建,随着方法的出栈而消失
  • 堆(java虚拟机堆):所有通过new关键字所创建的东西
  • 方法区:存储某一各类的字节码(.class)文件
  • 本地方法栈:主要是用来执行本地方法
    • 本地方法:被native关键字修饰的方法就是本地方法
    • 如:Object类中的hashCode方法就是一个本地方法,执行时,需要把这个方法加载到本地方法栈中,该方法是去调用c语言中的代码
  • 程序计数器:存储的是执行程序的行号
    • 为什么要把程序的行号存储到程序计数器中呢?
      • 程序的多线程

类的加载时机:当使用到某一各类的时候,才会把这个类加载到内存

public class Student {
	...
}

public class StudentDemo {
    
    public static void main(String[] args) {
        Student s1 = new Student() ;  
    }
    
}

/*
先把StudentDemo这个类的字节码文件加载到方法区,然后把main方法加载在栈内存,然后在把Student的字节码文件加载到方法区。
*/

2.2两个对象的内存图

  • 每new一次都会在堆内存中开辟一个新的内存空间
  • 方法中的this是谁?
    • 谁调用的方法,方法的this就是指谁

2.3两个引用变量指向同一个内存空间

Student s1 = new Student();
s1.setName("张三");

Student s2 = s1;
s2.setName("李四");

s1.show();//李四---0
s2.show();//李四---0

/*
上述代码创建了1个对象,只不过这个对象有两个名字: s1 , s2 
而s1和s2存储的都是同一个对象的地址值。
*/

多个引用变量指向同一个内存空间,不管是通过哪一个引用变量去操作,这个内存空间内的数据都会发生改变.

也就是说,引用变量所存储的是这篇内存空间的地址,当调用时,是获取这个空间的内存地址,从而进行操作

3 static关键字

3.1 static关键字的特点

static关键字翻译成中文是"静态"的意思,我们可以使用static来修饰成员变量,也可以使用static来修饰成员方法,被static修饰的成员变量,我们常常称之为类变量,被static修饰的成员方法我们常常称之为类方法
特点:

  • 被该类的所有对象所共享
  • 可以通过类名直接访问
//访问成员变量,并且这个成员变量没有被private所修饰
类名.变量名 = 具体的值;
//访问成员方法,并且这个成员方法没有被private所修饰
	//没有返回值
	类名.方法名(实际参数)
	//有返回值
	数据类型 变量名 = 类名.方法名(实际参数)

ps: 可以简化方法的调用,不用再创建对象.
是否需要把所有的方法都用static修饰呢?
不行,因为static修饰的成员生命周期(存在的时间)比较长,内存的占用时间也就越长

  • 随着类的加载而加载,消失而消失

3.2 static修饰的成员内存图

  • 被static修饰的成员是储存于静态区的
    静态区
    1.7以前:静态区是属于方法区内的
    1.8以后:静态区被移到堆内存中

3.3 static关键字注意事项

静态只能访问静态,非静态可以访问静态也可以访问非静态,并且在静态方法中不能存在this关键字

3.4 静态的使用场景

static可以修饰成员变量: 看这个成员变量是否需要被该类的所有对象所共享
static可以修饰成员方法:为了方便进行访问的调用可以直接使用static进行修饰,一般情况下体现在工具类中

public class ArrayUtils {

    // 遍历数组
    public static void print(int[] arr) {

        System.out.print("[");
        for(int x = 0 ; x < arr.length ; x++) {
            if(x == arr.length - 1) {
                System.out.print(arr[x]);
            }else {
                System.out.print(arr[x] + ", ");
            }
        }

        System.out.print("]");

    }

}

4 面向对象的三大特征

4.1 封装

  • 封装:就是一个东西把另外一部分的东西包裹起来
  • 现实生活中的封装: 电脑,插座,等等…
  • 程序的封装:
/*
1.方法
2.类
*/
  • 封装的好处:
    1. 提高了代码的复用性
    2. 提高了代码的维护性
    3. 提高了代码的安全性
  • 常见封装的使用:把方法所需要的的多个参数使用一个对象来进行封装,后期直接把参数传给对象即可
public void regist(String name , int age , String address , String phone ) {
	...
}

public void regist(Student s) {
	...
}

// 使用对象去封装方法的参数
Student s1 = new Student() ;
s1.setName("itcast") ;
s1.setAge(16) ;
s1.setAddress("北京") ;
s1.setPhone("6287638721") ;

// 调用方法
regist(s1);

4.2 继承

  • 继承:类与类的一种关系
  • 格式
public class 子类 extends 父类 {


}
public class B {
    
    public void show() {
        System.out.println("B....show...........") ;
    }
    
}

public class A extends B {			// A继承B,A常常将其称之为子类,B常常将其称之为父类

}
  • 特点:子类可以使用父类中的非私有成员
  • 好处:
    1. 提高了代码的复用性
    2. 提高了代码的维护性
    3. 是多态的前提

在整个继承体系中,顶层定义的都是这个继承体系的共性的内容,而底层定义的则是该体系中特有的内容

在java语言中,类和类之间只能是单继承,但可以使多层继承

4.3 多态

  • 多态: 同一个行为的不同体现方式
  • 前提
    • 需要存在继承或者实现的关系
    • 需要有方法的重写
    • 父类引用指向子类对象
  • 多态中的成员访问特点
    • 成员方法(非静态):编译看左边,执行看右边
    • 成员变量:编译看左边,执行看左边
  • 好处:提高了程序的灵活性
public class PersonDemo01 {

    public static void main(String[] args) {

        // 创建学生对象
        Student s1 = new Student() ;
        usePerson(s1);

        // 创建老师对象
        Teacher t1 = new Teacher() ;
        usePerson(t1);

        System.out.println("---------------------------------");

        // 使用多态的方式进行方法的调用
        Person p1 = new Student() ;
        p1.study();


        Person p2 = new Teacher() ;
        p2.study();

    }

    // 定义方法的参数为父类类型
    public static void usePerson(Person p) {        // Person p = new Teacher() ;
        p.study();
    }


}

4.4抽象类

  • 抽象方法:当我们在定义一个方法时,如果我们不能确定这个方法的方法体内容,此时就可以把该方法定义成抽象方法
public abstract 返回值类型 方法名(参数列表) ;
  • 抽象类:当某个类中出现抽象方法,name这个类就需要定义成抽象类
public abstract class 类名 {}
  • 抽象类的注意事项
    1. 抽象类不能实例化(就是不能直接创建对象)
    2. 有构造方法
    3. 抽象类中不一定有抽象方法,但有抽象方法的一定是抽象类
    4. 子类可以是抽象类,也可以是具体类(具体类需要重写所有的抽象方法)
  • 使用场景: 模板设计模式
    • 设计模式:设计模式是一套被反复使用的,多数人知晓的,经过分类编目的,代码设计经验的总结
    • 设计模式:就是一种代码书写的规范,一种套路
    • 使用设计模式的好处: 提高了代码的维护性
    • 在java中一共有23种设计模式
  • 模板设计模式:是一种常见的设计模式,它阐述的思想是:把抽象类整体就可以看成一个模板,模板中不能决定的东西定义成抽象方法,让使用模板的实现类取重写抽象方法实现需求
  • 模板是将一个事物的结构规律予以固定化,标准化的成果,它体现的是结构形式的标准化
// 写作文的模板类
public abstract class CompositionTemplate {

    // 模板方法:定义了代码结构的方法,我们可以将其称之为模板方法
    public void write() {

        // 标题
        System.out.println("<<我的爸爸>>");

        // 作文的正文
        body();

        // 结束语
        System.out.println("啊, 这就是我的爸爸....");

    }

    // 作文的正文的抽象方法
    public abstract void body();

}
public class TomCompositionTemplate extends CompositionTemplate {

    @Override
    public void body() {
        System.out.println("我把爸爸的区长.........");
    }

}
public class JackCompositionTemplate extends CompositionTemplate{

    @Override
    public void body() {
        System.out.println("我的爸爸是李刚.......");
    }

}

4.5 接口

  • 接口:当某一个类的方法都是抽象方法时,此时就可以定义成一个接口,接口其实就是去定义一些规则
public interface 接口名 {
    
    // 定义抽象方法
    
}
  • 特点
    1. 接口中的成员变量是默认存在修饰符public static final的
    2. 接口中没有构造方法
    3. 接口中的方法都是抽象方法(JDK1.7以前)
    4. 类和接口之间的关系是实现的关系,可以单实现也可以多实现
    5. 接口和接口之间的关系是继承关系,并且可以多继承
    public class 类名 implements 接口1 , 接口2.... {   
    }
    
  • 适配器的设计模式
public interface Inter {

    public abstract void aaa() ;

    public abstract void bbb() ;

    public abstract void ccc() ;

    public abstract void ddd() ;

    public abstract void eee() ;

    public abstract void fff() ;

}
public class InterAdaper implements Inter {			// 适配器类

    @Override
    public void aaa() {

    }

    @Override
    public void bbb() {

    }

    @Override
    public void ccc() {

    }

    @Override
    public void ddd() {

    }

    @Override
    public void eee() {

    }

    @Override
    public void fff() {

    }

}
public class MyInter extends InterAdaper {				// 子类

    @Override
    public void aaa() {
        System.out.println("MyInter.....aaaaa...");
    }

}

public class MyInter2 extends InterAdaper {				// 子类

    @Override
    public void ccc() {
        System.out.println("MyInter2........cccc....");
    }
}

5 接口中的新特性

5.1 默认方法

  • 概述:JDK1.8以后允许在接口中去定义非抽象方法,但是这个方法不许通过default关键字来修饰,那么这个方法就是默认方法
  • 解决的问题:接口的升级
public default 返回类型 方法名(参数列表) {}

public default void show() {
	System.out.println("default....show...method..........") ;
}

  • 注意事项:
    1. 子类可以不必重写这个默认方法,但如果需要重写,就需要去掉default关键字
    2. 默认方法的public关键字可以省略,但defafault不能省略
    3. 如果一个实现类实现了多个接口,那么这个类就必须重写重名的默认方法
public interface Inter1 {

	public default void show(){
		System.out.println("Inter1....show......") ;
	}

}

public interface Inter2 {

	public default void show(){
		System.out.println("Inter2....show......") ;
	}

}

public class InterImpl implements Inter1 , Inter2 {
    public void show(){
		System.out.println("InterImpl....show......") ;
	}
}


InterImpl interImpl = new InterImpl();
interImpl.show();

5.2 静态方法

public static 返回值类型 方法名(参数列表) {}
public static void show() {
    System.out.println("static....show....") ;
}
  • 注意事项
    1. 静态方法只能通过接口名进行调用
    2. public关键字可以省略,但static不能省略

5.3 私有方法

private static 返回值类型 方法名(参数列表) {}
private 返回值类型 方法名(参数列表) {}
private static void show() {
    System.out.println("static....show....") ;
}

private void method() {
    System.out.println("method....show....") ;
}
  • 常见的使用场景:就是把接口中默认的方法或者静态的方法中重复的代码抽取出来,定义在私有方法中
  • 注意事项:只能在本接口中使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aming_sth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值