1.面向对象和面向过程的含义
Java是一门纯面向对象的语言,那面向对象和面向过程的区别是什么呢,举个洗衣服的例子,面向过程的洗衣服是拿盆子、倒水、放衣服、放洗衣粉、手搓、甩干,这个过程中面向过程的语言按照一步步的步骤来写代码,如果是洗鞋子,就需要改变之前过程中的代码,就比较麻烦。对于面向对象的洗衣服,抽象出四个对象分别是人、洗衣机、洗衣粉、衣服、人把衣服和洗衣服倒入洗衣机,洗衣机开始工作洗衣服,这个过程完成了四个对象之间的互相交互。对于面向过程和面向对象是两种处理问题的思想,没有具体的好坏之分,不同情况不同分析。
2.类的定义与使用
2.1什么是类
类就是一个磨具,是用来对一个实体(对象)进行描述的,具体描述该实体(对象)的一些属性和功能,描述完成后计算机可以识别到。
2.2类的定义和格式
class ClassName{
field //字段、属性、成员变量
method // 成员方法
}
class是定义类的关键字,ClassName是类的名字(采用大驼峰的命名规则),{}中是类的主体
类中包含的内容成为类的成员,属性主要用来描述类,称为类的成员属性或成员变量,方法主要描述类的一些功能,称为类的成员方法。接下来定义一个学生类:
class Student {
public int id; //班级
public String name; //姓名
public int age; //年龄
public void read(){ //阅读
System.out.println("正在阅读");
}
public void writing(){ //写作
System.out.println("正在写作");
}
}
2.3类名的修改方法
3.类和对象
3.1类的实例化
类名 变量名 = new 类名();
定义了一个类相当于在计算机中定义了一种新的类型,与int,double类似,当一个类创建完成后,相当于创建好一个模型型,还没有创建与之对应实现类中的属性和功能的对象,因此用类去定义一个实例(对象),用类类型创建对象的过程成为类的实例化,Java中采用new关键字,上文中创建好了一个学生类,但是还没有创建该类的对象,因此我们简单实例化一个对象:
public static void main(String[] args) {
Student s1 = new Student();//创建
}
3.2成员的访问
通常我们采用.去访问对象的成员
public static void main(String[] args) {
Student s1 = new Student();
s1.read();
}
输出的结果是“正在阅读”
4.this引用
4.1为何要this引用
public class Date {
public int year;
public int month;
public int day;
public void setDay(int y,int m,int d){
year = y;
month = m;
day = d;
}
public void getDay(){
System.out.println(year + "/" + month + "/" + day);
}
public static void main(String[] args) {
Date d1 = new Date();
Date d2 = new Date();
Date d3 = new Date();
d1.setDay(2022,12,12);
d1.getDay();
}
}
输出结果是2022/12/12
看起来好像没什么问题,但是出现了以下问题该如何
1.形参名与变量名相同,具体是谁给谁赋值
public void setDate(int year,int month,int day){
year = year;
month = month;
day = day;
}
输出结果是0/0/0
2.当三个对象一起调用setDate()和getDate()时,此时函数主体不知道具体是哪个对象调用自己
4.2什么是this引用
为了避免上述出现的情况,我们就通过this引用,如下
public void setDate(int year,int month,int day){
this.year = year;
this.month = month;
this.day = day;
}
this引用指向当前对象(成员方法运行时,调用该方法的对象),即哪个对象调用了成员方法,this引用指向该对象
this引用的特性
1.哪个对象调用就是哪个对象的引用
2.this只能在“成员方法中”使用
5.对象的构造及初始化
5.1就地初始化
Java中局部变量需要立即赋值,否则会编译错误,然而在类的成员变量中,如果没赋值,会有一个默认值。
当然也可以进行就地的初始化,如下
public class Date {
public int year = 2002;
public int month = 10;
public int day = 5;
}
但是就地初始化比较麻烦,所以通常采用构造方法进行初始化
5.3构造方法
构造方法也称为构造器,名字必须与类名相同,创建对象时,编译器自动调用,在整个对象的周期只调用一次
public class Date {
public int year;
public int month;
public int day;
//带三个参数的构造方法
public Date(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
public void getDate(){
System.out.println(year + "/" + month + "/" + day);
}
public static void main(String[] args) {
Date d1 = new Date(2022,10,10);
d1.getDate();
}
}
此时我们发现,如果成员变量很多,我们自己写构造方法就会很麻烦,此时可以借用IDEA帮助我们自动生成构造方法
1.在IDEA界面右击选择Generate
2.选择Construct
3.全选成员变量
4,自动生产构造方法
1.构造方法就是对对象中的成员变量进行初始化
2.名字必须与类名相同
3.没有返回值类型
4.创建对象自动调用,在对象的生命周期只调用一次
5.构造方法可以重载,比如带三个参数或者带四个参数
6.如果用户没有写构造方法,编译器自己生成一份无参的构造方法
7.构造方法中可以用this调用其他的构造方法,但是this语句必须放在第一行且不能形成环
5.4默认初始化
Java中类成员变量如果不进行就地初始化也不会报错,当对象被创建后,对象中的成员硬件设置好了初始值
数据类型 | 默认值 |
---|---|
byte | 0 |
char | ‘\u0000’ |
short | 0 |
int | 0 |
long | 0L |
boolean | false |
float | 0.0f |
double | 0.0 |
6.封装
6.1什么是封装
面向对象的三大特性,封装继承多态
封装:隐藏对象属性和实现的细节,仅对外公开接口和对象进行交互,类似于计算机中我们看不到里面的硬件设备,只提供用户ucb接口、屏幕、键盘等,我们不关心计算机内部实现细节。
6.2访问限定符
访问权限符号用来控制类中的方法或者字段能否在类外直接使用
范围 | private | default(默认) | protected | public |
---|---|---|---|---|
同一包中的同一类 | 可 | 可 | 可 | 可 |
同一包中的不同类 | 可 | 可 | 可 | |
不同包中的子类 | 可 | 可 | ||
不同包中的非子类 | 可 |
6.3包
6.3.1什么是包
为了更好的管理类,把多个类收集在一起成为一组,称为软件的包,包是对类和接口等很好的组织方式,比如一个包中的类不想被其他包中的类使用,而且同一个工程中,不同的包里可以有名字相同的类。
6.3.2导入包中的类
例如Date类我们可以采用以下方式导入
1.java.util.Date
2.import java.util.Date
3.如果需要导入java.util中的其他类,可以采用*,例如java.util*这种写法当代码中需要哪一个类,就到util包中寻找再导入,而不是一次性把包中的所有类导入
4.第3点的导入方式通常会出现冲突如util和sql包中都有Date这样的类,代码不懂具体导入哪一个包中的Date
6.3.3自定义包
基本规则
*文件最上方加一个package语句指定该代码在哪个包中
*包名尽量指定成唯一的名字
*包名和代码路径相匹配,如果创建了一个包名为com.lff.demo1,那么会存在一个对应的路径来存储代码
*如果一个类中没有package语句,则被放在默认的包中
1.IDEA新建一个包
2.弹出的对话框输入包名,例如com.lff.demo1
3.在新建的包中创建类
4.此时对应磁盘上的结构被IDEA自动创建出来
5.此时新创建的文件最上方,出现了一个package语句
6.4封装的体现案例
在同一包中的不同类,一个类中的成员变量用private修饰,则在另一个类中不能直接访问该成员变量,因此需要用提供public修饰的成员方法来访问。
1.右键选择Generate
2.选择Getter和Setter
3.IDEA自动创建如下代码
public class Date {
private int year;
private int month;
private int day;
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
}
4.在另一个类中可以访问到被private修饰到的变量
public class Test {
public static void main(String[] args) {
Date d1 =new Date(2022,10,25);
System.out.println(d1.getDay());
}
}
7.static成员
7.1静态成员变量与静态方法
在Java中,被static修饰的成员成为静态成员,也称为类成员
静态成员变量的特性
1.不属于某个具体对象,是类属性,所有对象共享,不存储在对象的空间中,存储在方法区中。
2.可以通过对象访问,也可以通过类名访问,一般推荐类名访问
3.生命周期伴随类的一生
静态成员方法的特性
1.同上
2.不能在静态方法中,访问非静态的成员变量和方法(静态方法不依赖与对象,通过类名调用静态方法时,对象没被创建,因此不能访问类中依赖于对象的非静态成员变量和方法)
``
7.2 Static成员变量初始化
静态成员变量不能依赖于构造方法初始化(构造方法用在创建对象时初始化非静态的成员变量,静态成员变量不依赖于对象的创建)
1.就地初始化,在定义时直接赋初始值
2.静态代码初始化(往后看)
8 代码块
使用{}定义的一段代码称为代码块
普通代码块:定义在方法中的代码块,这种用法少见
构造代码块:构造在类中的代码块,也称为实例代码块**。一般用于初始化实例成员变量
静态代码块:一般用于初始化静态成员变量
public class Student {
private int age;
private String name;
private static int classroom;
//实例代码块
{
this.age=10;
this.name="lff";
System.out.println("实例代码块");
}
//静态代码块
static{
classroom = 1;
System.out.println("静态代码块1");
}
static {
System.out.println("静态代码块2");
}
public Student(){
System.out.println("不带参数的构造方法");
}
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
}
}
输出结果是
静态代码块1
静态代码块2
实例代码块
不带参数的构造方法
实例代码块
不带参数的构造方法
代码块总结
1.不管生成多少个对象,静态代码块只执行一次
2.实例代码块只有在创建对象时才会执行
3.如果一个类中有多个静态代码块,则按照代码中的位置顺序执行
4.优先级顺序是静态、实例、构造方法
5.静态成员变量是类的属性,因此是JVM加载类的时候开辟空间并初始化
9内部类
可以将一个类定义的另一个类的内部,前者称为内部类,后者称为外部类,根据定义的位置不同,分为实例内部类,静态内部类,局部内部类
public class Outclass{
public class InnerClass1{ //实例内部类,没有被static修饰,定义在成员位置 } public static class InnerClass2{ //静态内部类,被static修饰,定义在成员位置 } public void methodA(){ class InnerClass3{ //局部内部类,定义在方法中 } }
}
9.1实例内部类
没被static修饰的内部类称为实例内部类
1.实例内部类中可以访问外部类中任意的访问限定符修饰的成员
2.外部类和实例内部类中有相同的成员时优先访问自己的,如果要访问外部类同名的成员,必须:外部类类名.this.同名成员来访问
3.要访问实例内部类的对象,必须借助外部类如下
1.OutClass.InnerClass innerclass1 = new OUtClass().new InnerClass;
2. OutClass .InnerClass innerclass2 = outClass.new InnerClass();
4.外部类中,不能直接访问非静态的内部类中的成员,访问前必须先实例化内部类对象
9.2静态内部类
被static修饰的内部类称为静态内部类
1.静态内部类中只能访问外部类中的静态成员(因为经验内部类不依赖于对象)
2.创建静态内部类,不需要先创建外部类对象(同上)
OutClass.InnerClass innerClass = new OutClass.InnerClass();
9.3局部内部类
1.局部内部类只能在所定义的方法体中使用
2.不能被public、static修饰
3.很少使用
9.4 匿名内部类
10对象的打印
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Person person1 = new Person("lff",10);
System.out.println(person1);
}
}
输出结果:Person@1b6d3586
重写toString方法按照上述思路,即可打印
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public static void main(String[] args) {
Person person1 = new Person("lff",10);
System.out.println(person1);
}
}
输出结果:Person{name='lff', age=10}
对比两个代码块,不难发现出现了toString(),可以通过IDEA来实现,如下
1.右击鼠标,选中Generate
2.点击toString()
3.选择需要打印的成员属性
11 结语
本文详细的介绍了类和对象的一些概念总结以及使用方法,希望读者可以有所收获