1. 面向对象的初步认知
1.1 什么是面向对象
Java里面一切皆对象。
面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。
1.2 面向对象与面向过程
以面向对象方式来进行处理,就不关注洗衣服的过程,具体洗衣机是怎么来洗衣服,如何来甩干的,用户不用去关心,只需要将衣服放进洗衣机,导入洗衣粉,启动开关即可,通过对象之间的交互来完成的。
2. 类定义和使用
2.1 类的定义格式
// 创建类
class ClassName{
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法
}
class为定义类的关键字,ClassName为类的名字,{}中为类的主体。类中包含的内容称为类的成员。属性主要是用来描述类的,称之为类的成员属性或者类成员变量。方法主要说明类具有哪些功能,称为类的成员方法。
eg:洗衣机
class WashMachine{
public String brand; // 品牌
public String type; // 型号
public double weight; // 重量
public double lenght; // 长
public double weidth; // 宽
public double height; // 高
public String color; // 颜色
public void WashClothes(){ // 洗衣服
System.out.println("洗衣功能");
}
public void dryClothes(){ // 脱水
System.out.println("脱水功能");
}
public void SetTime(){ // 定时
System.out.println("定时功能");
}
}
注意事项:
类名注意采用大驼峰定义,方法名/变量名是小驼峰。
成员前写法统一为public,后面会详细解释。
此处写的方法不带 static 关键字. 后面会详细解释。
注意:
1. 一般一个文件当中只定义一个类
2. main方法所在的类一般要使用public修饰(注意:Eclipse默认会在public修饰的类中找main方法)
3. public修饰的类必须要和文件名相同
4. 不要轻易去修改public修饰的类的名称,如果要修改,通过开发工具修改。
要想修改main对应的类名:如下图
3. 类的实例化
3.1 什么是实例化
定义了一个类,就相当于在计算机中定义了一种新的类型,与int,double类似,只不过int和double是java语言自带的内置类型,而类是用户自定义了一个新的类型,比如上述的:PetDog类和Student类。它们都是类(一种新定义的类型)有了这些自定义的类型之后,就可以使用这些类来定义实例(或者称为对象)。用类类型创建对象的过程,称为类的实例化,在java中采用new关键字,配合类名来实例化对象。
class Dog{
public String name;
public String color;
public void barks(){
System.out.println(name+"汪汪叫!!!");
}
public void wag(){
System.out.println(name+"摇尾巴!!!");
}
}
public class Test {
public static void main(String[] args) {
Dog dog=new Dog();
dog.name="阿黄";
dog.color="黄色";
System.out.println(dog.name);
System.out.println(dog.color);
dog.barks();
dog.wag();
}
}
3.2 类和对象的说明
1. 类只是一个模型一样的东西,用来对一个实体进行描述,限定了类有哪些成员.
2. 类是一种自定义的类型,可以用来定义变量.
3. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
4. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。
一个类可以实例化多个对象。
4. this引用
‘.’ 主要表示调用。
class Date{
public int year;
public int month;
public int day;
public void DateMonth(){
System.out.println(year+"-"+month+"-"+day);
}
public void Dateage(int y,int m,int d){
year=y;
month=m;
day=d;
}
}
public class Test{
public static void main(String[] args) {
Date date = new Date();
// date.year = 2022;
// date.month=8;
// date.day=4;
date.Dateage(2022,8,22);
date.DateMonth();
}
}
两种方法都可以打印年月日。
如果将形参改为和类中参数相同,输出年月日将会输出0-0-0。
因为局部变量优先原则,在这个程序中只是形参给自己赋值了。根本没有赋值到成员变量当中。
想要真正将变量存到形参中,需要使用this引用
this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
this的三种使用方法:
1.this.成员变量
2.this.成员方法
3.this()访问构造方法
4.1 this引用的特性
1. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
2. this只能在"成员方法"中使用
3. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象
4. this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法
对象的引用传递给该成员方法,this负责来接收
联系:建立一个学生类有名字年龄等,一个方法中包含另一个方法,使用this。
class Stu{
public String name;
public int age;
public String classname;
public int score;
public void setstu(String name,int age,String classname,int score){
this.name=name;
this.age=age;
this.classname=classname;
this.score=score;
}
public void paintstu(){
System.out.println(name+" "+age+" "+classname+" "+score);
}
public void behave(){
this.paintstu();
System.out.println("正在考试");
}
}
public class Test{
public static void main(String[] args) {
Stu stu=new Stu();
stu.setstu("张三",15,"通信1班",100);
stu.behave();
}
}
5. 对象的构造及初始化
5.1 初始化种类一共有三种:
1.在main类中初始化。
类似这种。
2.就地初始化。
直接在定义的同时初始化。
3.就是构造方法
5.2 构造方法
构造方法就是没有返回值的方法,其方法名必须和类名相同。
根据上述代码,可知main类中调用构造方法的过程是
Student student=new Student();
总结:
1. 由上述代码可知,构造方法可同时存在多个,并且同名。并且在实例化时也可传参给构造方法。
2. 从以上结论我们可知,实例化对象后一定会创建构造方法,当我们没有手动创建构造方法时系统会自动给我们创建构造方法。
3. 并且当构造方法调用完成之后,我们的对象才能产生。
4.构造方法是可以重载的。
5.构造方法没有返回值。
5.3 this()的用法
由上述代码可知,this( )可以在一个构造方法中调用本类当中另一个构造方法。
this( )有一些限制条件比如说:必须放在构造方法里,必须放在构造方法的第一行。
上述带代码的运行顺序是:1.Student student=new Student();实例化变量
2.进入同样没有传参的构造方法1.
3.通过this()调用进入构造方法2.
4.接受传参并完成两个打印。
5.完成构造方法2回到构造方法1.
6.完成构造方法1打印。
7.完成对象的创建。
快捷键创造构造方法:
6. 封装
面向对象程序三大特性:封装、继承、多态。
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互
6.2 访问限定符
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符:
public指所有的类中店铺能用,而private只能在本类中使用。
public:可以理解为一个人的外貌特征,谁都可以看得到
default: 对于自己家族中(同一个包中)不是什么秘密,对于其他人来说就是隐私了(默认权限)
private:只有自己知道,其他人都不知道(封装主要使用private)
所以说包是什么?
6.3 封装扩展之包
6.3.1 包的概念
在Java中也引入了包,包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式,比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在不同的包中即可。
6.3.2 自定义包
如何新建包:
6.3.3 导入包中的类
1. 在文件的最上方加上一个 package 语句指定该代码在哪个包中.
2. 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.bit.demo1 ).
3. 包名要和代码路径相匹配. 例如创建 com.bit.demo1 的包, 那么会存在一个对应的路径 com/bit/demo1 来存储代码.
4. 如果一个类没有 package 语句, 则该类被放到一个默认包中(就是src).
一、 Java 中已经提供了很多现成的类供我们使用. 例如Date类:可以使用 java.util.Date 导入 java.util 这个包中的 Date类.
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
二、 如果需要使用 java.util 中的其他类, 可以使用 import java.util.*
‘ * ’代表导入所有的包,但不是一下子都导进来,是你用到谁就倒谁。
import java.util.*;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
所以说用到哪个类就导入对应包里面的对应的那个类。
三、 静态倒入(就是导入包后不用再加Math.pow的Math)几乎不用
7. static成员
这里的public static类型属于静态成员变量,不是对象,而是存储在方法区。
在使用时通过类名进行访问。并且在静态的方法内部不能访问非静态的成员或变量。
总结:
静态成员变量特性:
1. 不属于某个具体的对象,是类的属性,所有对象共享的,不存储在某个对象的空间中
2. 既可以通过对象访问,也可以通过类名访问,但一般更推荐使用类名访问
3. 类变量存储在方法区当中
4. 生命周期伴随类的一生(即:随类的加载而创建,随类的卸载而销毁)
静态方法特性:
1. 不属于某个具体的对象,是类方法
2. 可以通过对象调用,也可以通过类名.静态方法名(...)方式调用,更推荐使用后者
3. 不能在静态方法中访问任何非静态成员变量
4. 静态方法中不能调用任何非静态方法,因为非静态方法有this参数,在静态方法中调用时候无法传递this引用
5. 静态方法无法重写,不能用来实现多态(此处大家暂时不用管,后序多态位置详细讲解)。
7.2 static成员变量初始化
静态成员变量的初始化分为两种:就地初始化 和 静态代码块初始化。
1. 就地初始化
就地初始化指的是:在定义时直接给出初始值
2. 静态代码块初始化
8. 代码块
使用 {} 定义的一段代码称为代码块。根据代码块定义的位置以及关键字,又可分为以下四种:
1. 静态代码块
2. 实例代码块
3.局部代码块
4. 同步代码块(后续讲解多线程部分再谈)
从以上代码我们可知在实例化一个新成员变量时,的代码块生成顺序。
当类加载的时候静态代码块开始运行。但是静态代码块只会执行一次。
注意事项:
1. 静态代码块不管生成多少个对象,其只会执行一次
2. 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
3. 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
4. 实例代码块只有在创建对象时才会执行
9. 内部类
内部类分为四类:
1. 实例内部类/非静态内部类
2. 静态内部类
3. 局部内部类
4. 匿名内部类
9.1 实例内部类/非静态内部类
1. 成员内部类(普通内部类:未被static修饰的成员内部类 和 静态内部类:被static修饰的成员内部类)
2. 局部内部类(不谈修饰符)、匿名内部类
class OutClass{
//实例外部类
public int a;
int b=10;
public static void fuc(){
}
public static int c=10;
class IntClass{
//实例内部类
public int d;
int e=10;
//public static String f="实例内部类中的静态。";//error
}
}
public class Test{
public static void main(String[] args) {
OutClass outClass=new OutClass();
}
}
如何访问实例内部类:
实例内部类里不能有静态的对象。
但是见下图,加上一个final后实力内部类中的静态对象就不报错了。
final的作用时定义常量,是在程序编译时进行的。确定的常量只要初始化后就不能更改。
如上图,如果在内部类和外部类中同时出现了要输出的变量a,内部类的paint方法将优先输出离自己近的变量a(就近原则)
如果就是像输出外部类中的变量a:
拿到外部类的对象就可以了。
注意事项:
1. 外部类中的任何成员都可以在实例内部类方法中直接访问(就算外部类中的变量是private形式也可以)
2. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问
4. 实例内部类对象必须在先有外部类对象前提下才能创建
5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
9.2 静态内部类
静态内部类中所有类型的对象都可应用。
如何实例化静态内部类对象:
如上图,相比实例内部类,静态内部类明显跟加简单方便故使用率也较高。
如上图,在静态内部类打印方法中,b被成功打印,而a、c报错。故得出结论:
静态内部类当中,无法访问外部类的非静态内部类的对象,因为外部类的非静态成员需要通过外部类的对象的引用才能访问。
如果要像访问外部类的非静态变量,那么只需要像刚刚获取到外部类的实例化对象就可以了:
注意事项:
1. 在静态内部类中只能访问外部类中的静态,成员如果确实想访问,我们该如何做?
2. 创建静态内部类对象时,不需要先创建外部类对象。
9.3 局部内部类
就是方法中的类,但只能在该方法中使用,太过局限所以几乎不使用。
注意事项:
1. 局部内部类只能在所定义的方法体内部使用
2. 不能被public、static等修饰符修饰
3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
4. 几乎不会使用
9.4 匿名内部类
匿名对象只能使用一次。
以后再说。
10. 对象的打印
如果直接打印实例化对象,将输出一串代码:
当代码中有大量代码需要打印时,可以使用idea自带的快速大量打印节省时间
具体使用方法:
勾选需要打印内容。