学习资料
b站狂神说:https://www.bilibili.com/video/BV12J41137hu
访问修饰符
资料来源:https://www.runoob.com/java/java-modifier-types.html#protected-desc
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。
- default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
- public : 对所有类可见。使用对象:类、接口、变量、方法
- protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
- 接口及接口的成员变量和成员方法不能声明为 protected
修饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | N | |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |
非访问修饰符
为了实现一些其他的功能,Java 也提供了许多非访问修饰符。
static 修饰符,用来修饰类(静态)方法和类(静态)变量。
final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
abstract 修饰符,用来创建抽象类和抽象方法。
synchronized 和 volatile 修饰符,主要用于线程的编程。
封装
追求高类聚,低耦合
属性私有,提供get/set方法
package com.zy7y.oop;
/**
* @ProjectName: JavaSE
* @PackageName: com.zy7y.oop
* @Author: zy7y
* @Date: 2020/8/15 下午2:23
* @Description: 封装
*/
public class Packaging {
// 私有属性,只能在当前类使用
private String name;
// 提供对外的set方法设置值
public void setName(String name) {
this.name = name;
}
// 提供对外提供的get方法取到值
public String getName() {
return name;
}
}
启动文件
package com.zy7y.oop;
import sun.net.www.http.HttpClient;
import java.io.File;
/**
* @ProjectName: JavaSE
* @PackageName: com.zy7y.oop
* @Author: zy7y
* @Date: 2020/8/14 下午11:58
* @Description: 启动方法
*/
public class Application {
public static void main(String[] args) {
Packaging packaging = new Packaging();
packaging.setName("哈哈");
System.out.println(packaging.getName());
}
}
封装的意义
提供程序的安全性,保护数据
隐藏代码接口的实现
统一接口
增加可维护性
继承
关键字 extends
Java 中只有单继承,直接只能继承一个,间接可以继承多个
package com.zy7y.oop;
// 父类Person,所有类默认继承Object类
/**
* @ProjectName: JavaSE
* @PackageName: com.zy7y.oop
* @Author: zy7y
* @Date: 2020/8/15 上午12:04
* @Description: 构造方法: public 类名(), 无返回值
*/
public class Person {
private int age;
String name;
// 类中默认有一个无参构造方法
// 定义有参构造方法;构造方法的作用,初始化属性, 如果定义了有参构造方法,还需要无参构造方法,需要显示定义无参构造方法
public Person(String name){
this.name = name;
}
// alt + insert 快速生成构造方法
// 显示定义无参构造方法
public Person() {
this.name = "zy7y";
}
private void privateMethod(String msg){
System.out.println("私有方法,无法继承!" + msg);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.zy7y.oop;
//子类继承Person类
/**
* @ProjectName: JavaSE
* @PackageName: com.zy7y.oop
* @Author: zy7y
* @Date: 2020/8/15 下午2:31
* @Description:
*/
// 继承Person类, Teacher 为Person的子类/派生类
public class Teacher extends Person {
// 子类可以继承父类,非私有的属性与方法
private String name = "子类";
public void test(){
System.out.println(name);
System.out.println(this.name); // 调用本地的name
System.out.println(super.name); // 调用父类的name
}
}
super注意点:
super调用父类的构造方法,必须在构造方法的第一个
super 必须只能出现在子类的方法或者构造方法中
super和this不能同时调用构造方法
this、super区别:
this:代表当前对象的引用
super:代表父类对象的引用
this: 没有继承也可以使用
super:只能在继承条件后才可使用
this():本类的构造
super(): 父类的构造
方法重写
重写都是方法的重写,和属性无关,重写只能重写非静态方法,只有public修饰的方法。被fianl修饰的方法也不可以被重写
需要继承关系,子类重写父类的方法
方法名必须相同
参数列表必须相同
修饰符:范围可以被扩大,不能缩小 public > protected > default > private
抛出的异常:范围可以被缩小,不能扩大
重写:子类和父类的方法必须一致,方法体不同!
package com.zy7y.oop;
/**
* @ProjectName: JavaSE
* @PackageName: com.zy7y.oop
* @Author: zy7y
* @Date: 2020/8/15 下午2:31
* @Description:
*/
// 继承Person类, Teacher 为Person的子类/派生类
public class Teacher extends Person {
// 子类可以继承父类,非私有的属性与方法
private String name = "子类Teacher";
@Override
public void test() {
System.out.println(name);
System.out.println(this.name); // 调用本地的name
}
}
package com.zy7y.oop;
/**
* @ProjectName: JavaSE
* @PackageName: com.zy7y.oop
* @Author: zy7y
* @Date: 2020/8/15 上午12:04
* @Description: 构造方法: public 类名(), 无返回值
*/
public class Person {
private int age;
String name = "父类Person";
// 类中默认有一个无参构造方法
// 定义有参构造方法;构造方法的作用,初始化属性, 如果定义了有参构造方法,还需要无参构造方法,需要显示定义无参构造方法
public Person(String name){
this.name = name;
}
// alt + insert 快速生成构造方法
// 显示定义无参构造方法
public Person() {
this.name = "zy7y";
}
private void privateMethod(String msg){
System.out.println("私有方法,无法继承!" + msg);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void test(){
System.out.println("父类Person"); // 调用本地的name
}
}
多态
同一方法根据发送对象的不同而采用多种不同的行为方式
条件:
有继承关系
子类重写父类方法
父类引用指向子类对象
⚠️:多态是方法的多态,属性没有多态性
类型转换异常: ClassCastException
// 启动文件
package com.zy7y.oop;
/**
* @ProjectName: JavaSE
* @PackageName: com.zy7y.oop
* @Author: zy7y
* @Date: 2020/8/14 下午11:58
* @Description: 启动方法
*/
public class Application {
public static void main(String[] args) {
Teacher teacher = new Teacher();
teacher.test();
System.out.println();
// (向上转型)父类引用指向子类, 父类Person,子类Teacher, 对象能执行那些方法与左边类型有关,与new 无关
Person teacher1 = new Teacher();
teacher1.test();
// eat方法 只有子类有
teacher.eat();
// 父类中没有
teacher1.eat();
// (向下转型,可能会丢失一些方法)高类型 转 底类型,用强转,
((Teacher)teacher1).eat();
}
}
// 父类
package com.zy7y.oop;
/**
* @ProjectName: JavaSE
* @PackageName: com.zy7y.oop
* @Author: zy7y
* @Date: 2020/8/15 上午12:04
* @Description: 构造方法: public 类名(), 无返回值
*/
public class Person {
private int age;
String name = "父类Person";
// 类中默认有一个无参构造方法
// 定义有参构造方法;构造方法的作用,初始化属性, 如果定义了有参构造方法,还需要无参构造方法,需要显示定义无参构造方法
public Person(String name){
this.name = name;
}
// alt + insert 快速生成构造方法
// 显示定义无参构造方法
public Person() {
this.name = "zy7y";
}
private void privateMethod(String msg){
System.out.println("私有方法,无法继承!" + msg);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void test(){
System.out.println("父类Person"); // 调用本地的name
}
}
// 子类
package com.zy7y.oop;
/**
* @ProjectName: JavaSE
* @PackageName: com.zy7y.oop
* @Author: zy7y
* @Date: 2020/8/15 下午2:31
* @Description:
*/
// 继承Person类, Teacher 为Person的子类/派生类
public class Teacher extends Person {
// 子类可以继承父类,非私有的属性与方法
private String name = "子类Teacher";
@Override
public void test() {
System.out.println(name);
System.out.println(this.name); // 调用本地的name
}
public void eat(){
System.out.println("eat");
}
}
instanceof
// 对象 instanceof 类 ,判断是否有关系
System.out.println(person instanceof Object);
System.out.println(teacher1 instanceof Object);
System.out.println(teacher instanceof Object);