面向过程:面向过程即强调过程,比如说我们要做一个大型的项目,我们就把该项目划分为几个功能块(函数),把这几个功能块组合在一起就形成了一个项目,我们重点关注就是这几个函数(方法)。重点强调的就是每一个方法,每一个过程。
面向对象:面向对象即强调对象,比如我们要做一个大型的项目,我们换一种思想,我们找一个对象,该对象具备这几个功能,重点关注的是对象。
面向对象和面向过程的关系:面向对象是基于面向过程的,是建立在面向过程基础之上的。
举例:
面向过程:当我们去旅游的时候,我们需要亲自买机票、车票、门票等等。
面向对象:找一家旅游公司,只需要交钱、他就会帮你全部办好,使我们出行变得更方便了。
面向对象的好处:
面向对象是软件开发的一种思想,一种编程风格,面向对象开发方法认为客观世界是由对象组成的, 对象由属性和行为组成。任何对象都可以看做某 一类事物的实例,面向对象的方法主要是把事物给对象化(实例化)。
一类事物:人类、狗类、树类……
对象:一个人、一只狗,一棵树……
属性:人的属性有身高、年龄、姓名、性别……
行为:人会吃、喝、玩、乐……
类是对现实生活中一类具有共同特征的事物的抽象,描述 一类对象对象的属性和行为。
举例:人类
世界上所有的人统称为人类,人类具有很多的属性和行为,我们每一个个体都是一个对象,不同对象的属性和行为都有所差异。
在Java语言中,是如何定义类的?
在Java中定义类使用class关键字,定义格式如下👇
class 类名{
field//属性(成员变量或字段)
method//行为(成员方法)
}
class Human{
public String name;
public int age;
public String sex;
public void eat(){
System.out.println(name+":吃东西");//谁吃东西
}
public void sleep(){
System.out.println(name+":睡觉");//谁睡觉
}
}
相当于在计算机中定义了一种新的类型,与Java中的基本类型类似,类是自定义的新类型,我们可以通过这些类,实例出对象,称为类的实例化。
在java中采用new关键字配合类名来实例化对象。

public class Demo {
public static void main(String[] args) {
Human person1 = new Human();
person1.name = "Abel";
person1.eat();
Human person2 = new Human();
person2.name = "Anli";
person2.eat();
Human person3 = new Human();
person3.name = "Kari";
person3.eat();
}
}

注意事项:
类就相当于我们设计房子时的一张图纸,只设计出了一些东西,并没有实际的建筑存在,类的实例化相当于使用设计图建造出房子。

当我们在类中定义的成员变量和成员方法时一般不立即具体化,而是当实例化才开始调用和赋值,
案例引入:日期类
public class Test {
public static void main(String[] args) {
Data data = new Data();
data.setDate(2022,5,20);
data.printData();
}
}
class Data{
public int year;
public int month;
public int day;
public void setDate(int year, int month, int day){
year = year;
month = month;
day = day;
}
public void printData(){
System.out.println(year+"/"+month+"/"+day);
}
}
结果并不是我们想要的!!!
1.形参名和成员变量名相同?
public void setDate(int year, int month, int day){
year = year;
month = month;
day = day;
}
到底是谁给谁赋值呢?成员变量给成员变量?参数给参数?参数给成员变量?成员变量给参数?

可以看出,是参数给了参数!!那么该如何解决呢?
this引用指向当前对象,哪个对象调用this所在的方法,this就代表哪个对象,可见this的灵活性。


this引用的特性
上文我们使用一个方法给对象初始化, 每次需要调用方法初始化,比较繁琐,那么该如何解决呢?
构造方法(构造器),是一种特殊的方法,它是一个与类同名的方法,对象的创建就是通过构造方法来完成的,其功能主要完成对象的初始化,由编译器自动调用,并且在整个对象的生命周期内只调用一次。

public class Test {
public static void main(String[] args) {
Data data1 = new Data(2022,5,20);
data1.printData();
Data data2 = new Data(2022,5,21);
data2.printData();
Data data3 = new Data(2022,5,22);
data3.printData();
}
}
class Data{
public int year;
public int month;
public int day;
//构造方法一般情况下用public修饰
public Data(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
public Data(){
//无参构造方法
}
public void printData(){
System.out.println(this.year+"/"+this.month+"/"+this.day);
}
}
构造方法的特性:


构造方法中,可用通过this调用其他构造方法来简化代码
class Data{
public int year;
public int month;
public int day;
public Data(int year, int month, int day){
this(year,month);
this.day = day;
}
public Data(int year, int month){
this.year = year;
this.month = month;
}
public void printData(){
System.out.println(this.year+"/"+this.month+"/"+this.day);
}
}
注意:
总结:
一个局部变量未初始化,是不能够被使用的,而成员变量可以不初始化就可以使用。
成员变量默认初始化:
| 数据类型 | 默认值 |
|---|---|
| byte | 0 |
| char | ‘\u0000’ |
| short | 0 |
| int | 0 |
| long | 0L |
| float | 0.0f |
| double | 0.0 |
| boolean | false |
| reference | null |
| 成员变量就地初识化 | |
| 在定义变量时,就直接给初值 |
class Person{
String name = "maria";
int age = 10;
}
注意:代码编译完成后,编译器会将所有的初始化语句添加到各个构造方法中。

public static void main(String[] args){
//直接使用{}定义,没有什么特殊的作用,比较少见
{
int x = 10;
System.out.println(a);
}
}
构造代码块一般用于初始化实例成员变量。

public class Test {
public static void main(String[] args) {
Student student1 = new Student();
student1.show();
}
}

因为构造代码块是独立的,当我们创建对象时,如果构造代码块和构造方法同时存在时,先执行构造代码块,再执行构造方法。
注意:构造代码块,只要创建一个对象就会执行一次
用途:一般用于初始化实例成员变量

public class Test {
public static void main(String[] args) {
Student student1 = new Student();
student1.show();
Student student2 = new Student();
student2.show();
}
}

静态代码块,用static声明,JVM加载类时执行,所以执行顺序比实例代码块早。
用途:一般用来初始化静态成员变量
注意事项:
内部类:一个类定义在另一个类或者一个方法的内部。

定义在类中的类,定义位置与类成员所处的位置相同,也称为成员内部类。

class Demo1{
public static void main(String[] args) {
//创建实例内部类对象方法
//1.外部类名.内部类名 变量名 = new 外部类名().new 内部类名()
OuterClass.InnerClass innerClass1 = new OuterClass().new InnerClass();
//2.先创建外部类对象,在创建内部类对象
OutClass outClass1 = new OutClass();
OutClass.InnerClass innerClass2 = outClass1.new InnerClass();
}
}
总结:
使用static修饰的成员内部类

public class Demo {
public static void main(String[] args) {
//1.不需要创建外部类对象即可创建内部类
OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
innerClass.print();
}
}
总结:
定义在方法体或者{}中。

public class Demo {
public static void main(String[] args) {
//编译报错
OutClass.InnerClass innerClass = new OutClass().new InnerClass();
}
}
总结:
没有名字的局部内部类
为什么要使用匿名内部类?
是Java为了方便我们编写程序而设计的一个机制,往往我们在开发会遇到这样一个情况,一个接口/类的方法只要用到一次,但我们如果要去使用它,我们需要创建它的实现类/子类去实现重写,使用匿名内部类就可以无需创建新的类,就能满足我们的需求,也减少了代码的冗余。
//定义方法
new 接口/类名(参数列表){
实现方法1(){
}
实现方法2(){
}
...
}
例如我们想自定义二维数组排序的规则?
public class Demo {
public static void main(String[] args) {
int[][] array = {{5,1},{2,8},{8,1},{1,6},{5,2}};
Arrays.sort(array, new Comparator<int[]>() {
//1.匿名类中重写compare方法
@Override
public int compare(int[] o1, int[] o2) {
//第一个数不相等则升序排列,若相等,则按第二个数升序排列
if(o1[0] != o2[0]){
return o1[0]-o2[0];
}else {
return o1[1]-o2[1];
}
}
});
System.out.println(Arrays.deepToString(array));
}
}
总结:
概念:在面向对象的概念中,所有的对象都是通过类来描述的,但是反过来,并不是所有的类都是用来描述对象的,如果一个类中没有包含足够的信息来描述一个具体的对象,这样的类就是抽象类。
Java当中用Abstract关键字修饰的类,就叫做抽象类。
根本原因:无法描述一类事物的类
例子引入:比如现在想创建一个动物类,描述动物的一些共性,比如动物会吃东西,但是具体的动物吃的东西不尽相同,而我们在动物类中就很难去描述动物去吃什么东西。采用继承的思想,子类重新该方法,在添加具体的实现。
class Animal{
public void eat(){
}
}
class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃狗粮");
}
}
class Pig extends Animal{
@Override
public void eat() {
System.out.println("猪吃猪粮");
}
}
有的人可能会说这不也很好的实现了吗?
一般的类确实也能满足该需求,抽象类主要是用来适配子类的通用特性,是被用来创建子类的模板,实际上有些父类中的方法没有必要重新,当我们成使用抽象类来定义时,这样就可以区分哪些方法需要重写,具有提示的作用,也是我们设计程序的一种思想,我相信随着我们逐渐深入的学习,对这些设计会感触颇深。

总结: