目录
1. 面向对象的初步认知
1.1 什么是面向对象
1.2 面向对象与面向过程
2. 类定义和使用
2.1 简单认识类
2.2 类的定义格式
//class为定义类的关键字,ClassName为类的名字,{}中为类的主体。
// 创建类
class ClassName{
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法
}
//WashMachine 类名 采用大驼峰的形式
class WashMachine{
//属性、字段、成员变量:这些成员变量是定义在方法外部 类的内部的
public String brand; // 品牌
public String type; // 型号
public double weight; // 重量
public double length; // 长
public double width; // 宽
public double height; // 高
public String color; // 颜色
public void washClothes(){ // 洗衣服
System.out.println("洗衣功能");
}
public void dryClothes(){ // 脱水
System.out.println("脱水功能");
}
public void setTime(){ // 定时
System.out.println("定时功能");
}
}
3. 类的实例化
3.1 什么是实例化
class PetDog {
public String name;//名字
public String color;//颜色
public int age; //年龄
// 狗的属性
public void barks() {
System.out.println(name + ": 旺旺旺~~~");
}
// 狗的行为
public void wag() {
System.out.println(name + ": 摇尾巴~~~");
}
}
public class Test {
PetDog dog1 = new PetDog();
//可以通过new实例化多个对象
PetDog dog2 = new PetDog();
PetDog dog3 = new PetDog();
}
3.2 类和对象的说明
![](https://img-blog.csdnimg.cn/direct/9091d97a6e414d8091e1ab2ef1482832.png)
public class Test {
public static void main(String[] args) {
PetDog dog1 = new PetDog();
dog1.name = "阿黄";
dog1.age = 2;
dog1.color = "黄色";
System.out.println("姓名 :" +dog1.name);
System.out.println("年龄 :" +dog1.age);
System.out.println("颜色 :" +dog1.color);
dog1.barks();
dog1.wag();
PetDog dog2 = new PetDog();
dog2.name = "阿cai";
dog2.age = 3;
dog2.color = "白色";
System.out.println("姓名 :" +dog2.name);
System.out.println("年龄 :" +dog2.age);
System.out.println("颜色 :" +dog2.color);
dog2.barks();
dog2.wag();
}
}
注:只要new就会产生新的对象只要是新的对象就是有新的内存。只需要通过对象的引用去访问对象的成员变量即可或者是成员方法。
1、引用可以指向引用吗?
Dog dog1 = new Dog();
Dog dog2 = dog1;
不能说明是引用指向引用,正确的理解是引用只能指向对象,所以dog2这个引用指向了dog1这个引用所指向的对象。
2、一个引用能不能同时指向多个对象?
Dog dog1 = new Dog();
dog1 = new Dog();
dog1 = new Dog();
dog1 = new Dog();
不可以,最终dog1这个引用只能存储一个对象的地址。
3、这个dog2这个引用指向一个null对象?
Dog dog2 = null;
不是的,dog2这个引用不指向任何一个对象。
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 = year;
month = month;
day = day;
}
public void printDate() {
System.out.println(year + "/" + month + "/" + day);
}
public static void main(String[] args) {
// 构造三个日期类型的对象 d1 d2 d3
Date d1 = new Date();
d1.setDay(1854,6,4);
d1.printDate();
}
}
public void setDay(int year, int month, int day){
year = year;
month = month;
day = day;
}
此时相当于局部变量优先使用,所以并没有将我们想要的值赋值成功。
public void setDay(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
我们在需要赋值的变量前加上this. ,这个时候就可以正确赋值了。
注:建议该加this的都要加,能保证我们的代码长时间都可以正常运行。
4.2 什么是this引用
![](https://img-blog.csdnimg.cn/direct/86b9a2023a374d2a8afbe5ffd2a06725.png)
注:谁调用this,this就是谁。
4.3 this引用的特性
5. 对象的构造及初始化
5.1 如何初始化对象
public static void main(String[] args) {
int a;
System.out.println(a);
}
// Error:(26, 28) java: 可能尚未初始化变量a
数据类型 | 默认值 |
byte | 0 |
char | '\u0000' |
short | 0 |
int | 0 |
long | 0L |
boolean | false |
float | 0.0f |
double | 0.0 |
reference | null |
5.2 构造方法
5.2.1 概念
public class Date {
public int year;
public int month;
public int day;
// 构造方法:
// 名字与类名相同,没有返回值类型,设置为void也不行
// 一般情况下使用public修饰
// 在创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次
public Date(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
System.out.println("Date(int,int,int)方法被调用了");
}
public void printDate(){
System.out.println(year + "-" + month + "-" + day);
}
public static void main(String[] args) {
// 此处创建了一个Date类型的对象,并没有显式调用构造方法
Date d = new Date(2021,6,9); // 输出Date(int,int,int)方法被调用了
d.printDate(); // 2021-6-9
}
}
5.2.2 特性
public Date(){
this(1900,1,1);
}
public Date(int year, int month, int day) {
this();
}
/*
无参构造器调用三个参数的构造器,而三个参数构造器有调用无参的构造器,形成构造器的递归调用
编译报错:Error:(19, 12) java: 递归构造器调用
*/
注:构造方法是可以发生重载的。
this代表当前对象的成员变量
this.成员变量 | 可以访问该成员变量 |
this.成员方法 | 可以访问该成员方法 |
this() | 调用另一个构造方法 |
如何访问对象当中的成员呢? 一般是通过对象的引用 + 点号 来访问成员变量和成员方法的 |
在前面讲了默认初始化,还有一种初始化方法叫就就地初始化较为简单,见代码。
public class Date {
public int year = 1900;
public int month = 1;
public int day = 1;
public Date(){
}
public Date(int year, int month, int day) {
}
public static void main(String[] args) {
Date d1 = new Date(2021,6,9);
Date d2 = new Date();
}
}
就地初始化:在声明成员变量时,就给了初始值。
6. 封装
6.1 封装的概念
public void eat(){
System.out.println(this.name + "正在吃饭!");
}
当我们要实现封装时,可以将public -> private,但是这样修改后权限缩小了。
private void eat(){
System.out.println(this.name + "正在吃饭!");
}
实现封装后在这个的类外不能直接使用这个方法了。
6.2 访问限定符
范围 | private | default | protected | public |
同一个包中的同一个类 | 可以 | 可以 | 可以 | 可以 |
同一个包中的不同一个类 | 可以 | 可以 | 可以 | |
不同包的子类 | 可以 | 可以 | ||
不同包的非子类 | 可以 |
注:default并不是限定符,如同意思是默认的,什么都不写的情况下。
6.3 封装扩展之包
6.3.1 包的概念
6.3.2 导入包中的类
//第一种方法
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
//为了方便我们通常使用第二种方法
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一个毫秒级别的时间戳
System.out.println(date.getTime());
}
}
第二种方法可以使用 import 语句导入包。
也可以可以使用import static导入包中静态的方法和字段。
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 30;
double y = 40;
// 静态导入的方式写起来更方便一些.
// double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
double result = sqrt(pow(x, 2) + pow(y, 2));
System.out.println(result);
}
}
6.3.4 自定义包
package com.bit.demo1;
public class Computer {
private String cpu; // cpu
private String memory; // 内存
public String screen; // 屏幕
String brand; // 品牌
public Computer(String brand, String cpu, String memory, String screen) {
this.brand = brand;
this.cpu = cpu;
this.memory = memory;
this.screen = screen;
}
public void Boot(){
System.out.println("开机~~~");
}
public void PowerOff(){
System.out.println("关机~~~");
}
public void SurfInternet(){
System.out.println("上网~~~");
}
package com.bite.demo2;
import com.bite.demo1.Computer;
public class TestComputer {
public static void main(String[] args) {
Computer p = new Computer("HW", "i7", "8G", "13*14");
System.out.println(p.screen);
// System.out.println(p.cpu); // 报错:cup是私有的,不允许被其他类访问
// System.out.println(p.brand); // 报错:brand是default,不允许被其他包中的类访问
}
}
// 注意:如果去掉Computer类之前的public修饰符,代码也会编译失败
6.3.5 常见的包
7. static成员
public class Student{
// ...
public static void main(String[] args) {
Student s1 = new Student("Li leilei", "男", 18, 3.8);
Student s2 = new Student("Han MeiMei", "女", 19, 4.0);
Student s3 = new Student("Jim", "男", 18, 2.6);
}
}
7.1 static修饰成员变量
public class Student{
public String name;
public String gender;
public int age;
public double score;
public static String classRoom = "Bit306";
// ...
public static void main(String[] args) {
// 静态成员变量可以直接通过类名访问
System.out.println(Student.classRoom);
Student s1 = new Student("Li leilei", "男", 18, 3.8);
Student s2 = new Student("Han MeiMei", "女", 19, 4.0);
Student s3 = new Student("Jim", "男", 18, 2.6);
// 也可以通过对象访问:但是classRoom是三个对象共享的
System.out.println(s1.classRoom);
System.out.println(s2.classRoom);
System.out.println(s3.classRoom);
}
}
注:被static修饰的成员变量不属于对象属于类,是类变量,存放在方法区。
类的成员变量有2种:
1、静态成员变量
1.属于类的,不属于对象的
2.类名 + 点号来访问静态成员变量【合理的,对象来访问不合理】
2、非静态成员变量 / 普通成员变量
1.属于对象的,每实例化一个对象,都会有一个对于的非静态成员变量,每个对象都有
2.对于的引号 + 点号来访问
7.2 static修饰成员方法
public class Student{
// ...
private static String classRoom = "Bit306";
// ...
public static String getClassRoom(){
return classRoom;
}
}
public class TestStudent {
public static void main(String[] args) {
System.out.println(Student.getClassRoom());
}
}
注:设置成静态方法后,调用不需要对象的,所以不用加 this. 。
public static String getClassRoom(){
System.out.println(this);
return classRoom;
}
// 编译失败:Error:(35, 28) java: 无法从静态上下文中引用非静态 变量 this
public static String getClassRoom(){
age += 1;
return classRoom;
}
// 编译失败:Error:(35, 9) java: 无法从静态上下文中引用非静态 变量 age
public static String getClassRoom(){
doClass();
return classRoom;
}
// 编译报错:Error:(35, 9) java: 无法从静态上下文中引用非静态 方法 doClass()
7.3 static成员变量初始化
2. 静态代码块初始化
8. 代码块
8.1 普通代码块
public class Main{
public static void main(String[] args) {
{ //直接使用{}定义,普通方法块
int x = 10 ;
System.out.println("x1 = " +x);
}
int x = 100 ;
System.out.println("x2 = " +x);
}
}
// 执行结果
x1 = 10
x2 = 100
8.2 构造代码块
public class Student{
//实例成员变量
private String name;
private String gender;
private int age;
private double score;
public Student() {
System.out.println("I am Student init()!");
}
//实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main {
public static void main(String[] args) {
Student stu = new Student();
stu.show();
}
}
// 运行结果
I am instance init()!
I am Student init()!
name: bit age: 12 sex: man
8.3 静态代码块
public class Student{
private String name;
private String gender;
private int age;
private double score;
private static String classRoom;
//实例代码块
{
this.name = "bit";
this.age = 12;
this.gender = "man";
System.out.println("I am instance init()!");
}
// 静态代码块
static {
classRoom = "bit306";
System.out.println("I am static init()!");
}
public Student(){
System.out.println("I am Student init()!");
}
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
}
}