1.面向对象思想
1.1什么是面向对象
面向对象(Object-Oriented,简称OO)是一种软件开发方法、编程范式和抽象方针,它基于逻辑对象的概念来构建编程语言、系统或软件。面向对象的核心思想是将现实世界的事物抽象为对象,通过创建、利用和操纵这些可重用的对象来执行特定任务、过程或达到目标。
而JAVA就是一门纯面向对象语言,在面向对象的世界里,一切皆对象。面向对象是一种解决问题的方法,主要依靠对象之间的交互来完成一件事情。
1.2面向对象和面向过程的区别
1.思考方式:
-
面向过程:面向过程强调的是解决问题的步骤,即先做什么、再做什么、最后做什么。它关注的是过程,将问题分解为一系列步骤,并通过函数或方法来实现这些步骤。
-
面向对象:面向对象强调的是将问题分解为各个对象,这些对象具有属性和方法。它关注的是对象之间的交互和协作,通过对象来模拟现实世界中的事物和过程。
2.代码结构:
-
面向过程:面向过程的代码结构通常比较清晰,按照步骤进行编写。然而,由于过程之间可能存在紧密的依赖关系,导致代码的可重用性和可维护性较差。
-
面向对象:面向对象的代码结构更加模块化和结构化。它将数据和操作数据的方法封装在一起,形成一个个独立的对象。这些对象之间通过接口或消息进行通信,降低了对象之间的耦合度,提高了代码的可重用性和可维护性。
3.可维护性:
-
面向过程:由于面向过程的代码结构通常比较紧密,一个过程可能需要依赖于多个其他过程。因此,当需要修改某个过程时,可能会影响到其他过程的正常运行。这种紧密的依赖关系使得面向过程的代码难以维护和扩展。
-
面向对象:面向对象的代码结构更加模块化和结构化,每个对象都是独立的。因此,当需要修改某个对象时,只需要修改该对象本身的代码即可,不会影响到其他对象的正常运行。这种低耦合的特性使得面向对象的代码更加易于维护和扩展。
举个例子来说明面向对象和面向过程:
1.你要洗衣服,你要做以下事情:
2.你要洗衣服,于是你把衣服丢进洗衣机里面:
发现什么区别了吗?1是面向过程,2是面向对象。
在面向对象时,你不需要知道洗衣机是怎么工作的,你只需要告知洗衣机这个对象自己的需求,它就能帮你完成,这样的编程思想使得对象之间的依赖性更低,代码的耦合性更低,这样就更加方便以后的维护和扩展。
要注意的是:面向对象和面向过程没有好坏之分,都有其专门的使用场景。
2.类和对象的定义和使用
2.1类的定义格式
语法:
class 类名{
字段/属性(定义在类当中,方法之外,也叫成员变量)
方法
}
// 创建类
class ClassName{
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法
}
2.2类的实例化
public class Dog {
public String name;
public int age;
public void eat(){
System.out.println(name + " 正在吃饭");
}
}
然后在main方法中进行类的实例化:
public class Text {
public static void main(String[] args) {
Dog dog = new Dog();
}
}
实例化后,dog就是一个对象,dog的类型就是我们自定义的类型Dog,此时我们可以通过 . 来对类中的成员进行访问,例如 : dog.name dog.age
public class Text {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = "大黄";
dog.age = 5;
}
}
可以把名字和年龄打印出来:
public class Text {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = "大黄";
dog.age = 5;
System.out.println(dog.name);
System.out.println(dog.age);
}
}
命令行输出:
注意事项
-
new 关键字用于创建一个对象的实例.
-
使用 . 来访问对象中的属性和方法.
-
同一个类可以创建多个实例。
-
类中定义的成员变量都有默认值,引用类型默认为null,基础数据类型默认为对应的零值。
3.this关键字
3.1为什么要有this
先看一个例子:
public void setDog(String n, int a) {
name = n;
age = a;
}
我们在Dog类中添加一个成员方法setDog,用于对dog对象的初始化,
public class Text {
public static void main(String[] args) {
Dog dog = new Dog();
dog.setDog("大黄", 5);
System.out.println(dog.name);
System.out.println(dog.age);
}
}
然后我们调用dog.setDog就可以完成对dog对象的初始化,
public void setDog(String name, int age) {
name = name;
age = age;
}
我们会发现打印的结果变了
public void setDog(String name, int age) {
this.name = name;
this.age = age;
}
最后的结果便回到我们想要的结果
3.2什么是this
public void setDog(Dog this,String name, int age) {
this.name = name;
this.age = age;
}
可以理解为是谁在调用setDog,那么谁就是this,所以这里的this指的就是dog这个对象。这也就是为什么当多个对象都访问成员方法时,也能准确的把每个对象的参数都正确的传入到方法中。
4.对象的创建和初始化
4.1如何初始化对象
前文说到,我们可以使用set有关方法进行初始化,比如setDog。
但是这样意味着我们每创建一个对象,都要使用setDog进行初始化,太麻烦了,那么有没有更好用的方法呢,当然有,我们可以调用构造方法来进行对象的初始化。
4.2构造方法
4.2.1构造方法的概念
class Dog {
public String name;
public int age;
public Dog(String name, int age){
this.name = name;
this.age = age;
}
}
就像这样,那我们怎么调用呢
public class Text {
public static void main(String[] args) {
Dog dog = new Dog("大黄", 5);
System.out.println(dog.name);
System.out.println(dog.age);
}
}
在new对象的同时这样调用就行了,打印结果依然是:
4.2.2构造方法的特性
-
名字必须与类名相同
-
没有返回值类型,设置为void也不行
-
创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
-
构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)
class Dog {
public String name;
public int age;
public void eat(){
System.out.println(name + " 正在吃饭");
}
//无参构造方法
public Dog(){
this.name = "张三";
this.age = 18;
}
//含两个参数的构造方法
public Dog(String name, int age){
this.name = name;
this.age = age;
}
}
以上两个构造方法,参数不一样,构成了重载。
注意:当类中不含构造方法时,编译器会自动提供一个没有参数和任何内容的构造方法。
在构造方法中,可以通过this来调用其他构造方法,例如:
class Dog {
public String name;
public int age;
public void eat(){
System.out.println(name + " 正在吃饭");
}
//无参构造方法
public Dog(){
this("张三",18);
}
//含两个参数的构造方法
public Dog(String name, int age){
this.name = name;
this.age = age;
}
}
或者:
class Dog {
public String name;
public int age;
public void eat(){
System.out.println(name + " 正在吃饭");
}
//无参构造方法
public Dog(){
this.name = "张三";
this.age = 18;
}
//含两个参数的构造方法
public Dog(String name, int age){
this();
this.name = name;
this.age = age;
}
}
要注意的是,构造方法中,用this来调用其他构造方法必须放在构造方法的第一行。
4.3就地初始化
在类中定义成员变量时,可以就地进行初始化:
class Dog {
public String name = "大黄";
public int age = 5;
}
5.封装
5.1封装的概念
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互
5.2访问限定修饰符
-
default权限指:什么都不写时的默认权限
-
访问权限除了可以限定类中成员的可见性,也可以控制类的可见性
6.static修饰的成员变量和成员方法
6.1static修饰的成员变量
-
不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
-
既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
-
类变量存储在方法区当中
-
生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)
6.2static修饰的成员方法
-
不属于某个具体的对象,是类方法
-
可以通过对象调用,也可以通过类名.静态方法名(...)方式调用,更推荐使用后者
-
不能在静态方法中访问任何非静态成员变量
-
静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用
-
静态方法无法重写,不能用来实现多态
6.3静态成员变量的初始化
6.3.1就地初始化
与非静态成员变量一样可以就地初始化,这里就不多讲了。
6.3.2静态代码块初始化
什么是静态代码块初始化,别急,往后看
7.代码块
7.1普通代码块
public class Text {
public static void main(String[] args) {
{
//直接使用{}定义
int a = 10;
System.out.println(a);
}
}
}
7.2构造代码块(实例代码块)
如:
class Dog {
public String name;
public int age;
{
name = "大黄";
age = 5;
}
}
7.3静态代码块
class Dog {
public String name;
public int age;
public static String color;
static{
color = "黄";
}
}
注意:
-
静态代码块不管生成多少个对象,其只会执行一次
-
静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
-
如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
-
实例代码块只有在创建对象时才会执行