面向对象
从面向过程到面向对象
面向过程:
-
步骤清晰简单,逐步解决问题,思考每一步需要做什么。
-
适合处理一些简单问题。
面向对象:
-
分类思维,思考解决这个问题需要哪些分类,然后对这些分类进行单独思考。最后才对分类下的细节进行面向过程的思考。
-
面向对象适合处理复杂问题,尤其适合处理需要多人协作的问题。
-
面向对象并不是面向过程的替代品,而是一种宏观的思考分析的方式。具体到微观操作仍然需要面向过程的思路去处理。
什么是面向对象
核心思想
面向对象即面向对象编程,面向对象编程的本质:以类的方式组织代码,以对象的形式封装数据。
抽象
-
将代码的共同点抽取出来以组织成一个类。
-
对象是具体的事物,而类是抽象的,是对对象的抽象。
封装
-
以对象的形式封装数据,对外只留取一个接口来访问。
-
封装会尽可能的隐藏对象内部的实现细节。
-
通过某些关键类提供的方法来实现对隐藏信息的操作和访问,这些关键类甚至不允许外部调用。
继承
-
类之间的关系,规定子类可以继承父类。
(套娃警告) -
每个子类只能继承一个父类,但是它的父类上面可能也有父类,即多层继承。
(禁止套娃) -
提高代码的复用性,子类可以使用父类的属性和方法,也可以自己定义方法来重写覆盖父类的方法。
多态
-
一个行为具有多种不同的表现形式和形态。
-
通过继承实现对象的向上或者向下转型,即使用父类实现子类对象,或者将父类对象还原成子类对象。
值传递和引用传递
值传递
示例代码:
/**
* 值传递
*/
public class Demo6 {
public static void main(String[] args) {
String name = null;
change(name);
System.out.println(name);
//打印结果为null,值没有被改变。
}
public static void change(String name) {
name = "乌鸦";
}
}
值传递是将参数的值传递进方法进行执行,如果方法没有返回值,则该值不会被改变。
引用传递
示例代码:
/**
* 引用传递
*/
public class Demo7 {
public static void main(String[] args) {
Person person = new Person();
change(person);
System.out.println(person.name);
//打印结果乌鸦
}
public static void change(Person person) {
person.name = "乌鸦";
}
}
同样调用没有返回值的方法,但是这次我们传递进去的是一个Person对象,所以传进去的是这个对象的地址,改变的是对象的属性。
对象实例使用练习
创建一个类
示例代码:
public class Student {
//属性
String name;
int age;
//方法
public void study() {
System.out.println(this.name + "在学习");
}
public void game() {
System.out.println("这个" + this.age + "岁的学生,在玩游戏。");
}
}
this标签表示当前类,常用于重名的变量和属性区分。
主程序调用
示例代码:
public class Application {
public static void main(String[] args) {
//实例化类,生成一个该类的对象
Student student = new Student();
//给对象的属性赋值
student.name = "乌鸦";
student.age = 18;
//通过对象调用类中的方法
student.study();
//打印结果:乌鸦在学习
student.game();
//打印结果:这个18岁的学生,在玩游戏。
}
}
构造器
-
当我们写出一个类的时候,即使这个类里面什么东西都不写,也会存在一个方法,这个方法就叫做构造函数,这个构造函数是隐式定义的。
-
这个方法的名字和类名完全一致,默认是无参构造,没有内容也没有参数。
-
构造器的作用实际只有两个
-
我们new一个类为对象的时候,本质就是在调用这个类的构造器。
-
通过有参构造函数用来给这个类的属性赋初始值。
-
-
如果定义了一个有参构造函数,则默认的无参构造函数必须显示定义。
-
不管是无参还是有参构造函数都不能有返回值!也不能写viod。
-
热知识:IDEA可以通过Alt+Insert快速生成构造函数。
无参构造函数
示例代码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
public class Student {
String name;
int age;
public Student() {
}
public void study() {
System.out.println(this.name + "在学习");
}
public void game() {
System.out.println("这个" + this.age + "岁的学生,在玩游戏。");
}
}
这里是通过编译后的class文件,我们可以看到我们在源文件中并没有写Student方法,但是编译后还是生成了这个方法,这就是默认的无参构造函数。
有参构造函数
示例代码:
public class Student {
//属性
String name;
int age;
//无参构造函数
public Student() {
}
//有参构造函数
public Student(String name) {
this.name = name;
}
//构造函数的重载
public Student(String name, int age) {
this.name = name;
this.age = age;
}
//方法
public void study() {
System.out.println(this.name + "在学习");
}
public void game() {
System.out.println("这个" + this.age + "岁的学生,在玩游戏。");
}
}
当一个类中使用了有参构造函数,就一定要把无参的构造函数写出来。有参构造函数是通过方法的重载来实现的。
主程序调用
示例代码:
public class Application {
public static void main(String[] args) {
//实例化类,生成一个该类的对象
//通过构造函数初始化对象
Student crow = new Student("乌鸦", 18);
//构造函数的重载,初始化对象。
Student ming = new Student("小明");
//没有初始化的属性,手动赋值。
ming.age = 14;
//通过对象调用类中的方法
crow.study();
//打印结果:乌鸦在学习
crow.game();
//打印结果:这个18岁的学生,在玩游戏。
ming.study();
//打印结果:小明在学习
ming.game();
//打印结果:这个18岁的学生,在玩游戏。
}
}
定义了有参构造函数后,我们可以在new对象的时候使用构造函数给对象的属性初始化值。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人