本文来自老师授课内容,已获得老师同意在此当做本人学习笔记记录



紧接上一篇Java面向对象基础

在这里插入图片描述

类和对象

类:是一组相关属性和行为的集合

对象:是一类事物的具体体现。对象是类的一个实例,必然具备该类事物的属性和行为

类是对一类事物的描述,是抽象的。
对象是一类事物的实例,是具体的。
类是对象的模板,对象是类的实体。

public class Test {
	public static void main(String[] args) {
       //实例化: 类名   对象名  =  new  类名();
		Phone huawei = new Phone();
		System.out.println(huawei.brand);
		System.out.println(huawei.price);
		System.out.println("--------------------------------------");
		//成员变量赋值
		huawei.brand = "mate40";
		huawei.price = 2000;
		System.out.println(huawei.brand);
		System.out.println(huawei.price);
		huawei.call("导员");  //调用成员方法
    }  
}
class Phone{  //类	
	String brand;//相关属性,成员变量:类中方法外
	int price;//相关属性
	public void call(String person) {//行为的集合,成员方法,和以前定义的方法几乎一样,只是把static去掉了
		System.out.println("给"+person+"打电话");
	}
}

封装

面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改。

封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。要访问该类数据,必须通过指定方式。

将属性隐藏起来,若需要访问某个属性,提供公共方法对其访问

private int name = 10; //成员变量
	//getter & setter  一种封装
	public int getName() {
		return name;
	}

	public void setName(int name) {
		if(name > 0 ) {this.name = name;}
		else {this.name = 11;}
	}

封装的好处

加强了程序代码的安全性。
适当的封装可以提升开发效率,让代码更容易理解与维护,也加强了代码的安全性

Java中的四种访问控制符是:

  1. private(私有的):表示只能在本类中访问,其他类无法访问。

  2. default(默认的):表示只能在同一包中访问,其他包无法访问。

  3. protected(受保护的):表示可以被本类、同一包中的类和不同包中的子类访问,其他不同包的类无法访问。

  4. public(公共的):表示可以被任何类、任何包中的类访问。

这些控制符控制了类、方法、属性的访问范围,提高了程序的安全性和可维护性。在设计程序时,应该根据需要选择适当的访问控制符。

封装的实现步骤

一般对成员变量使用private(私有)关键字修饰进行隐藏,private修饰后该成员变量就只能在当前类中访问。
提供public修饰的公开的getter、setter方法暴露其取值和赋值。

定义类定义属性、方法,需要首先指明访问权限

//正确写法
public class Student {
    // 定义属性时使用private权限
    private String name;
    private int age;
    private String grade;

    public Student() {
        super();
    }

    public Student(String name, int age, String grade) {
        super();
        this.name = name;
        this.age = age;
        this.grade = grade;
    }

    // 需要为每一个私有的属性提供一对set/get方法,让其他类使用
    // 定义方法时使用public权限

    public void showInfo() {
        System.out.println("学生姓名:" + name + ",年龄:" + age + ",班级:" + grade);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        // this.name = name;
        if (name != null && !name.trim().equals("")) {
            this.name = name;
        } else {
            System.out.println("姓名不能为空");
        }
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        // this.age = age;
        if (age >= 6 && age <= 18) {
            this.age = age;
        } else {
            System.out.println("年龄不合法(应在6~18岁之间)");
        }
    }

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        // this.grade = grade;
        if (grade != null && !grade.trim().equals("")) {
            this.grade = grade;
        } else {
            System.out.println("班级不能为空");
        }
    }
}

封装是面向对象的三大特征之一,合理隐藏,合理暴露。一般会把成员变量使用private隐藏起来

一般封装通过getter和setter方法暴露其访问体现出来

对应的测试类:

public class TestStudent { 
	public static void main(String[] args) { 
		Student stu = new Student("Tom", 20, "男"); 
		stu.showInfo(); stu.setAge(8); 
		stu.setAge(30); stu.showInfo();
	}
}

继承

子类能继承父类的属性和方法 extends

继承就是java允许我们用extends关键字,让一个类和另一个类建立起一种父子关系。(子类 extends父类)

提高代码复用性,减少代码冗余,增强类的功能扩展性

子类继承父类即拥有父类定义的所有属性和方法,同时要增加自己的属性和方法

1、Java是单继承的(一个孩子只有一个父亲,一个父亲可以有多个孩子),一个父类可以有多个子类
2、可以有多级继承,祖宗类java.lang.Object

Java中子类更强大

1、提高代码的复用性

2、是多态的前提

案例:

public class Emp {
//父类

	public void clock() {
		System.out.println("打工人上班打卡");
	}

}

①、子类创建对象时,在构造方法中必须先调用父类的构造方法
②、使用super() 调用父类构造方法
③、调用父类无参构造方法 super() 可以省略
④、使用在子类构造方法中 this()和super()不能同时出现

public class Worker extends Emp{
//子类   只允许单继承
	
	public void shift() {
		System.out.println("工人需要倒班");
	}
	
}

通过测试验证子类继承父类后拥有父类定义的所有属性和方法

public class 继承测试 {
	public static void main(String[] args) {
		Worker worker = new Worker();
		worker.clock();
		worker.shift();		
	}
}

子类实例化过程

我们刚才(案例一中)在定义类时并没有加属性

子类在创建对象的过程就叫实例化

Student称为子类(派生类),People称为父类(基类或超类)
作用:当子类继承父类后,就可以直接使用父类公共的属性和方法了,而且是必须调用父类的

public class Student extends People { }

在这里插入图片描述

接着以上面的案例为例子:

public class Emp {
//父类
	String name;
	double sal;
	
	public Emp() {
		//super();
		//调用父类的无参构造方法
        System.out.println("Emp无参构造方法执行了");
	}

	public Emp(String name, double sal) {
		super();
		this.name = name;
		this.sal = sal;
	}

	public void clock() {
		System.out.println("打工人上班打卡");
	}

}

Emp无参构造方法执行了这句话被打印了出来

接下来是子类

public class Worker extends Emp{
	//子类创建对象时,在构造方法中必须先调用父类的构造方法
	//使用super() 调用父类构造方法
	//调用父类无参构造方法 super() 可以省略
	//使用在子类构造方法中 this()和super()不能同时出现
	
	String workshop; 
	
	public Worker() {
		//super();
	}
//子类拥有的属性 两部分继承  继承父类和自己定义的
	
	public Worker(String name, double sal, String workshop) {
		super(name, sal); //父类的属性调用父类有参构造方法初始化
		this.workshop = workshop; //自己的属性代码完成
	}

	public void shift() {
		System.out.println("工人需要倒班");
	}
}

在上面声称有参构造方法时要选择有参的
在这里插入图片描述

继承中构造方法的访问特点

1、子类中所有的构造方法默认都会访问父类中的无参的构造方法
2、因为子类会继承父类中的数据,可能还会使用父类中的数据,所以子类初始化之前,需要对父类进行初始化。
3、每个子类构造方法的第一句默认都是:super()

如果父类中没有无参构造方法,只有带参构造方法,怎么办?
1、通过super关键字显示调用父类的有参构造方法
2、父类中自己单独定义一个无参构造方法

JavaBean

JavaBean的思维导图如下图所示:

在这里插入图片描述

标准代码,一种标准规范

class A{
	//成员变量
    //构造方法:一定有无参的,建议有有参的
    //成员方法
    //getter & setter 
}

多态

在这里插入图片描述

多态是一个行为有多个不同的表现形式。指对象可以有多种形态

小明同学是个学生,同时他是个人。既有学生的形态又有人的形态,一个对象有多种形态就是对象的多态性。

父类名 对象名 = new 子类名()

接口名 对象名 = new 实现名()

多态的前提:

1、有继承extends或实现implements(有继承/实现关系)

2、方法重写,如果方法一样就没意义 (有方法重写(多态侧重行为多态))

3、父类引用指向子类对象(有父类引用指向子类对象)

案例一

USB接口有void open(), close()

类Mouse实现 USB接口,click

类KeyBoard实现 USB接口,type

public class Test {
	public static void main(String[] args) {
		USB obj = new Mouse();//接口名  对象名 =  new  实现名()
		                      //父类名  对象名 =  new 子类名()
		obj.open();
    }  
}
interface USB {
    void open();
    void close();
}
class Mouse implements USB{
    @Override
    public void open() {
        System.out.println("open mouse");
    }
    @Override
    public void close(){
        System.out.println("close mouse");
    }
    public void click(){
        System.out.println("点击鼠标");
    }
}
class KeyBoard implements USB {
    @Override
    public void open() {
        System.out.println("open keyBoard");
    }
    @Override
    public void close() {
        System.out.println("close keyBoard");
    }
    public void type(){
        System.out.println("敲击键盘");
    }
}

电脑使用鼠标键盘 Laptop

public class Test {
	public static void main(String[] args) {
		Laptop lp = new Laptop();
		USB usb = new Mouse(); //多态
		lp.useUSB(usb);
    }  
}
interface USB {
    void open();
    void close();
}
class Mouse implements USB{
    @Override
    public void open() {
        System.out.println("open mouse");
    }
    @Override
    public void close(){
        System.out.println("close mouse");
    }
    public void click(){
        System.out.println("点击鼠标");
    }
}
class KeyBoard implements USB {
    @Override
    public void open() {
        System.out.println("open keyBoard");
    }
    @Override
    public void close() {
        System.out.println("close keyBoard");
    }
    public void type(){
        System.out.println("敲击键盘");
    }
}

class Laptop{
	public void useUSB(USB usb) {  //电脑使用USB
        usb.open();
        if(usb instanceof Mouse) {//instanceof的作用:判断前面对象usb能不能当后面类型的实例Mouse
        	Mouse m = (Mouse)usb; //类型转换,调用特有方法
        	m.click();
        }
        else {
        	KeyBoard keyBoard = (KeyBoard)usb;
            keyBoard.type();
        }
        usb.close();
    }
}

案例二

1、先定义一个接口

public interface Run {
	void print();

}

2、接着写实现类

实现开宾利

public class Bcar implements Run{
//宾利
	@Override
	public void print() {
		// TODO 自动生成的方法存根
		System.out.println("今天开宾利");
	}

}

实现开大众

public class Dcar implements Run{
//大众
	@Override
	public void print() {
		// TODO 自动生成的方法存根
		System.out.println("今天开大众");
	}

}

现在代码中有实现关系,有方法的重写实现

要有向上的转型——引用数据类型转换

3、再新建一个测试类

public class 多态测试 {
	public static void main(String[] args) {
		Run run = new Dcar();
		run.print();   //调用重写方法出现多态
		run = new Bcar();  //给run变量重新赋值
		run.print();
	}

}

下面我们看一下多态的优点:易于扩展

增加新代码,老代码不需要改动

刚才写了两辆车,一辆宾利、一辆大众,接下来我们再加一个能力,让车能开

通过方法的形参体现需要

需要的是能力——接口

public class Car {
	//需要开车的能力
	public void carRun(Run run){
		System.out.println("我已经准备好开车");
		run.print();
		
	}

}

多态优点测试

public class 多态优点测试 {
	public static void main(String[] args) {
		Car car = new Car();
		car.carRun(new Dcar());
		
	}

}

静态关键字

Java中的关键字是具有特殊含义的单词或标识符,它们已经被Java语言用作它们原有的含义,不能用于其他目的。

  1. class:定义一个类
  2. public:定义公共的类、方法或属性
  3. private:定义私有的方法或属性
  4. protected:定义受保护的方法或属性
  5. static:定义静态的方法或属性
  6. final:定义不可更改的常量或方法,或者将类定义为不可继承的
  7. abstract:定义抽象类或方法
  8. interface:定义接口
  9. implements:实现接口
  10. extends:继承类
  11. new:创建新的对象
  12. this:引用当前对象
  13. super:引用父类对象
  14. try:定义一个尝试性的代码块
  15. catch:处理try代码块中抛出的异常
  16. throw:抛出异常
  17. throws:声明可能会抛出的异常
  18. finally:定义一个代码块,无论try代码块是否抛出异常都会执行
  19. if:定义一个条件语句
  20. else:定义一个条件语句的可选操作
  21. switch:定义一个多条件语句
  22. case:switch语句中的每个条件分支
  23. break:跳出循环或switch语句
  24. continue:跳过当前循环的剩余代码并开始下一个迭代
  25. do:定义一个do-while循环
  26. while:定义一个while循环
  27. for:定义一个for循环
  28. foreach:定义一个增强型for循环
  29. return:从方法中返回值
  30. void:定义一个方法不返回值
  31. true:代表真(布尔类型)
  32. false:代表假(布尔类型)
  33. instanceof:判断对象是否是某个类的实例
  34. import:导入类或包
  35. package:定义一个包
  36. synchronized:同步线程
  37. volatile:定义一个易失性变量
  38. assert:定义一个断言(用于调试)

以上是Java中的一些关键字及其用法
由于这些关键字已经被Java语言用作其原有的含义,因此不能将它们用于其他目的


静态方法:

  1. 调用静态方法不需要创建对象,通过[类名.]直接调用
  2. 静态方法的方法体中不能使用非静态属性(局限,输出就是输出,不能有连接符,不能把所有方法都变成静态的)
  3. 工具类中的方法一般定义成静态的

静态代码块:

  1. 静态代码块中的代码只会在类加载时执行一次
  2. 某一块代码只需要运行一次时

以下是类似的代码例子:

public class Class {
    private String name;
    private int age;
    public static String school = "xxx中学";
    //静态属性 全类共享  类加载时(第一次使用)创建空间
    //定义类时某一个数据只需要一个值定义成静态属性

    //静态方法
    public static void sing() {
        System.out.println("学生在学校要好好学习");
    }
    //静态代码块
    static {
        System.out.println("Class 加载了");
    }
}

测试类

public class 静态测试 {
    public static void main(String[] args) {
        Class c1 = new Class();
        Class c2 = new Class();
        //静态属性通过 [类名.]访问
        System.out.println(Class.school);
        Class.sing();
    }
}

总结

面向对象的三大特点是:封装、继承、多态

封装知识点:

定义类定义属性、方法,需要首先指明访问权限

定义属性时使用private权限

需要为每一个私有的属性提供一对set/get方法,让其他类使用

定义方法时使用public权限

定义完整类步骤 :

1、定义私有属性

2、定义两个构造方法

3、定义set/get方法

4、定义其他方法

set是赋值的意思
setAge 是给年龄赋值
get是获取

get——直接获取成员变量的值获取的操作
set——就是给我们成员变量赋值操作,赋值的操作.

继承知识点:

类名后面使用extends 继承父类

只允许单继承,只允许有一个父类

子类继承父类即拥有父类定义的所有属性和方法,同时要增加自己的属性和方法

子类创建对象时,在构造方法中必须先调用父类的构造方法

使用super() 调用父类构造方法

调用父类无参构造方法 super() 可以省略

使用在子类构造方法中 this()super()不能同时出现

子类拥有的属性有两部分继承,继承父类和自己定义的

什么情况下使用到继承模式呢?
多个类中存在相同的成员属性或者方法,使用继承模式将每个子类相同代码直接抽取出来存放在父类中。

继承中变量的访问特点
在子类方法中访问一个变量:
子类局部范围找
子类成员范围找
父类成员范围找
如果都没有则报错
即遵循就近原则!

先查找局部变量→当前类中成员属性变量→父类中→如果类中没有该变量的话,直接报错

1、好处:
提高了代码的复用性(多个类相同的成员属性和方法可以放到一个类当中)
提高了代码的维护性(如果方法的代码需要修改,只需修改一处即可)

2、弊端:
继承让类与类之间产生了关系,类的耦合性也增加了,当父类发生变化时候,子类也不得不跟着变化,削弱了子类的独立性。

抽象类知识点:

抽象类 不能创建对象
抽象类 需要子类继承才有意义
抽象类中能定义抽象方法也可以定义非抽象方法
抽象类实际应用中当做模板来使用
抽象类中要包含非抽象的方法,可以让子类继承后直接使用
抽象类要包含抽象方法,让子类继承后去重写

多态知识点:

多态指的是不同对象对同一行为做出的不同响应成为多态

多态出现必要条件:
1、类中要有继承或实现关系
2、要有方法的重写或实现
3、要有向上的转型

调用重写方法出现多态
引用变量存储的是哪一个类的对象就会调用哪一个类的方法

多态优点:易于扩展(增加新代码,老代码不需要改动)
多态缺点:不能使用子类特有功能

多态中的转型
1、向上转型(多态机制)从子到父,父类引用指向子类对象
2、向下转型(强转)从父到子,父类引用转为子类对象

在这里插入图片描述

final 作用

final是一种修饰符
修饰变量,变量变常量只能被赋值一次
修饰方法,方法不能被子类重写
修饰类,不能被子类继承

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐