Java面向对象知识总结-上 1
文章目录
一, 对面向对象的理解和总结
1.1, 什么叫面向对象?
-
在程序中
使用对象来映射现实中的事物
,使用对象的关系来描述事物之间的联系
,这种思想就是面向对象. -
面向对象和面向过程的对比:
面向过程就是分析解决问题所需要的步骤,然后用函数把这些步骤一一实现
.
面向对象是把要解决的问题按照一定的规则划分为多个独立的对象,然后通过调用对象的方法来解决问题
.
1.2, 面向对象的三大特点
封装, 继承, 多态
封装: 将对象的
属性和行为封装
起来,避免外界直接访问,而只提供一些公有的方法供外界使用,比如访问属性的getXX()和修改属性的setXX().使用封装提高了代码的安全性和可重用性.
继承: 在无需编写原类的情况下,对原类进行扩展
,增强代码的复用性.
多态: 在一个类中定义的属性和方法被其他类继承后,可具有不同的数据类型或不同行为,使得同一属性和方法在不同类中具有不同的语义.
1.3 Java语言的特点
二, 类与对象
2.1, 类与对象的定义
类: 类是模版,
确定对象
拥有的特征(属性
)和行为(方法
).
对象:对象是类的实例,去具体实现一个类的行为.
2.2, 对象的创建所经过的过程
- eg: Person p = new Person();
1, Person p = null,声明
一个Person类型的变量p, 此时是在栈中开辟了一个 p=null的空间
;
2, new person(),创建
Person类的一个实例对象, 此时是在堆中开辟了一块空间
;
3, '='是把Person实例对象在堆中的地址赋值给栈中的变量p.
拓展:
Java基本数据类型和引用数据类型传值的理解: (▷)(※)
- 内存中的栈用于保存局部变量的值,而堆是用于保存一些动态产生的数据(如, new()后产生的实例化对象).
- 无论基本类型的变量,还是引用类型的变量,都是存放到栈中的.
但是! 基本类型的变量在栈里是直接保存它对应的值
. 而引用类型声明的变量在栈中只是保存一个指向堆里具体空间的地址
,
通过这个地址去到堆中找到引用类型的具体信息.- 所以我们可以知道, 基本数据类型在栈中占用一块内存,而引用对象类型在栈和堆中共占用两块内存.
对象间的引用传递,实际上传递的是堆空间的使用权
.
举个栗子:
2.3, 类的封装
所谓类的封装就是指在定义一个类时,将类中的属性私有化,即利用private关键字去修饰这些属性,私有属性只能在他所在的类中访问.
为了能让外界访问私有属性,需要提供一些使用public修饰的公有方法,其中包括用于获取属性值的 getXxx() 方法 和 设置属性值的 setXxx();
封装的好处:(※)
提高了数据的安全性
别人不能够通过 变量名.属性名 的方式来修改某个私有的成员属性操作简单
封装后,多个调用者在使用的时候,只需调用方法即可,调用者不需要再进行判断隐藏了实现
实现过程对调用者是不可见的,调用者只需调用方法即可,不知道具体实现过程
- 代码示例:
class Person{
private String name;
private int age;
private String sex;
public void setName(String _name) {
this.name = _name;
}
public String getName() {
return this.name;
}
public void setAge(int _age) {
if(_age <= 0) {
System.out.println("格式不合法!");
}else{
this.age = _age;
}
}
public int getAge() {
return this.age;
}
public String getSex() {
return this.sex;
}
public void setSex(String _sex) {
this.sex = _sex;
}
///
public void introduce() {
System.out.println("Hello, I am "+name+", age: "+age+", sex: "+sex);
}
public static void main(String[] args) {
Person p = new Person();
p.setName("sb");
p.setAge(14);
p.setSex("gay");
p.introduce();
}
2.4, 构造方法 (为对象赋值/做出某些行为)
在实例化对象后,我们通常通过直接访问对象的属性或是调用setXX()方法为属性赋值. 如果需要在
实例化对象的同时就为属性赋值,就需要用到构造方法
.
2.4.1, 构造方法的定义
如果我们想在实例化对象的同时就为
对象赋值
,或者是在实例化对象时做出某些行为
,我们可以使用构造方法.
在一个类中定义的方法满足下面三个条件,则可称其为构造方法:
方法名与类名相同
;- 方法前面
没有返回值
类型的声明;- 方法
不使用return
返回一个值
2.4.2, 构造方法的种类
- 代码示例:
class Person{
1.无参的构造方法
public Person() {
System.out.println("无参的方法执行了哦");
}
2.有参的构造方法
public Person(int x) {
System.out.println("有参的构造方法执行了,并且"
+ "我得到了来自new Person()的值为: "+x);
}
///主方法,程序入口
public static void main(String[] args) {
Person p = new Person();
Person p1 = new Person(488568);
}
2.4.3, 构造方法的重载
- 代码示例:
一个person类,有男人,有女人,大人开奥迪去搬砖,女人在家生小孩
class Person{
public Person(String carName, String work) {
System.out.println("我是男人,我开着"+carName+",去"+work);
}
public Person(int childNum){
System.out.println("我是女人,我生了"+childNum+"个小孩");
}
///主方法,cheng'xu'ru'kou
public static void main(String[] args) {
Person man = new Person("奥迪","搬砖");
Person woman = new Person(53456);
}
在Java中的每个类都至少有一个构造方法,如果在一个类中没有定义构造方法,系统会自动为这个类创建一个默认的空构造方法,这个默认的构造方法没有参数,方法体也没有代码,啥也不做.
需要强调的一点,当我们已经定义了有参的构造方法,系统不会再生成默认的无参构造方法,所以我们需要使用无参构造方法的话,需要自己再定义一个无参构造.
2.5, this关键字
this 关键字用于在方法中,访问对象的其他成员.
2.5.1, this关键字适用的四种场景
- 通过this关键字可以明确地去
访问一个类的成员变量
,解决与局部变量的命名冲突;
- 代码示例:
private String name;
public void setName(String _name) {
this.name = _name;
}
public String getName() {
return this.name;
}
- 通过this关键字
调用成员方法
- 代码示例:
class Person{
public void sayHi(){
xxxxxx
}
public void speak(){
this.sayHi();
}
}
在构造方法中调用其他的构造方法
构造方法是在实例化对象时被JVM自动调用的,在程序中不能像调用其他方法一样调用构造方法,可以在一个构造方法中使用this([参数1,参数2,…)""的形式来调用其他构造方法.
- 代码示例:
class Person{
public Person(){
System.out.println("无参的方法被调用了");
}
public Person(int age){
this();
System.out.println("有参的方法被调用了");
}
public static void main(String[] args){
Person p = new Person(18);
}
}
指代当前对象
方法只有一份,对象可以有多个。 java中通过对象调用方法,
this就是指调用当前方法的那个对象
。 实现的原理应该就是对象调方法的时候,隐式的把这个对象的引用传给了方法,所以在方法中可以通过this拿到这个对象。
2.5, JVM的垃圾回收(单独补充)
2.6, static 关键字 (成员变量. 成员方法 和代码块)
在定义一个类时,只是在描述某类事物的特征和行为,并未产生具体的数据,只有new()创建该类的实例的对象时,系统才会为对象分配空间存储数据.
被static关键字修饰的不需要创建对象去调用,直接根据类名就可以去访问.
- static可以修饰成员变量、成员方法,被修饰的成员属于类。
被static修饰的成员变量、成员方法随类的加载而加载,只加载一次;存储在静态区;先于对象存在。
2.6. 1静态变量
有时候,我们希望某些特定的数据在内存中只有一份,而且能够被一个类的所有实例对象所共享.
在一个Java类中,可以使用static关键字去修饰成员变量,该变量就被称为静态变量. 静态变量被所有实例共享,可以使用"类名.变量名"
的形式去访问.
当然也可以通过"类的实例对象.变量名"访问.
示例代码:
public class Student {
static String schoolName = "NJU";
static String careerName = "Graduate Student";
public static void main(String[] args) {
System.out.print("We both are the "+Student.careerName
+" from "+Student.schoolName);
}
}
Caution: Static关键字
只能用于修饰类的成员变量
,不能修饰局部变量
2.6.2 静态方法
如果我们希望在不创建对象的情况下,就可以调用某个方法,即
对象和方法不必捆绑在一起
. 我们可以使用Static关键字去修饰
类中定义的方法,在访问时通过类名.方法名
去访问.
当然也可以通过类的实例对象.方法名访问.
public class Student {
static String schoolName = "NJU";
static String careerName = "Graduate Student";
public static void introduce() {
System.out.println("Hi, i am a "+careerName+" from "+schoolName);
}
public static void main(String[] args) {
Student.introduce();
}
}
Caution:
静态方法
可以直接访问静态变量和静态方法,不能直接访问普通成员变量或成员方法
。反之,成员方法可以直接访问类变量或静态方法。- 静态方法中,不能使用 this关键字。
在一个静态方法中,只能访问用static修饰的成员
,原因在于未被staic修饰的成员需要创建对象才能访问, 而静态方法在被调用时可没有创建任何的对象噢!
2.6.3 静态代码块
在Java类中,使用一对大括号包围起来的若干行代码块被称为一个代码块. 用static修饰后的叫静态代码块.
当类被加载时,静态代码会执行. 由于类只加载一次,因此静态代码只执行一次! 所以我们经常使用静态代码块对类的成员变量进行初始化
.
示例代码:
public class Test {
static {
System.out.println("静态代码块执行了噢");
}
public static void main(String[] args) {
///两次示例化Person类,只会执行一次静态代码块
Person p1 = new Person();
Person P2 = new Person();
}
}
class Person{
static {
int count =66;
System.out.println("Person类的静态代码块被执行咯!");
}
}
- 运行结果如下:
虚拟机首先加载Test类,同时执行test类中的静态代码块,紧接着会调用main(), 在该方法中两次创建并实例化了Person类的对象,但是Person类的静态代码块只执行了一次.
2.6.4单例模式(单独补充)
2.6, 内部类
Java中,允许在一个类的内部定义类,这样的类叫做内部类,这个内部类所在的类叫外部类. 根据内部类的位置,修饰符或定义的方式, 可以分为 成员内部类, 静态内部类, 方法内部类.
2.6.1, 成员内部类
- 在一个类中除了可以定义成员变量,成员方法,还可以定义类,这样的类叫做成员内部类.在
成员内部类中可以访问外部类的所有成员
,外部类不可以直接访问内部类的所有成员
,无论内部类的成员是公有的还是私有的!
示例代码:
package InnerClassDemo;
/成员内部类
public class School {
public String schoolName = "希望小学";
private int fee = 666;
public class Student{
public String studentName="小坏蛋";
private String addr="我肾ten DC";
///内部类的方法不能是静态的
public void introduce(){
System.out.println("i am a student in "+schoolName+
"and my school fee is "+fee);
}
}
public void advertise(){
外部类无法直接访问内部类的成员变量或方法
///外部类如果要访问内部类,必须得到内部类的对象,
//然后利用内部类对象去访问内部类的成员
Student stu = new Student();
System.out.println("my school has a student called "+stu.studentName
+", his home addr is "+stu.addr);
}
public static void main(String[] args) {
1.外部类通过在其方法内新建内部类对象去调用内部类的成员变量和方法.
School sch = new School();
sch.advertise();
///2. 实例化内部类对象 外部类.内部类 xx = new 外部类(). new 内部类();
/// 实例化内部类,调用内部类的方法.
School.Student sch1 = new School().new Student();
sch1.introduce();
}
}
- 如果想直接通过外部类去访问内部类,则
须通过外部类对象
去创建内部类对象 - 具体格式:
外部类名.内部类名 变量 = new 外部类名().内部类名();
2.6.2, 静态内部类
-
可以使用static关键字来修饰一个成员内部类,该内部类就叫做
静态内部类
,它可以在不创建外部类对象的情况下被初始化
. -
格式:
外部类名.内部类名 变量名 = new 外部类名.内部类名();
示例代码:
class Outer{
private static int num = 6;
///下面方法定义了一个成员方法,方法中访问内部类;
public void test(){
Inner inner = new Inner();
inner.show();
}
//下面定义了一个成员内部类
static class Inner{
void show(){
///在成员内部类的方法中访问外部类的成员变量
System.out.println("num="+num);
}
}
}
public class test{
public static void main(String[] args){
//通过test()间接访问内部类
Outer outer = new Outer();
outer.test();
///这是直接访问内部类,并调用内部类的方法show()
Outer.Iner inner = new Outer.Inner();
inner.show();
}
}
静态内部类中只能访问外部类的静态变量;
在静态内部类中,可以定义静态的成员,而在非静态的内部类中,不允许定义静态成员!
2.6.3, 方法内部类
方法内部类是指在成员方法中定义的类,只能在当前方法中被使用.
示例代码:
class Outer{
private int num = 4;
public void test() {
///在方法中创建并使用内部类
class Inner{
void show() {
System.out.println("num = "+num);
}
}
///方法内部类只能在方法中使用
//但是方法内部类也是可以访问外部类成员的奥
Inner inner = new Inner();
inner.show();
}
}
//test
public class test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.test();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)