JavaSE-面向对象(This, super,Static, 封装,继承,覆写)

1. This

        1.1 this是什么

        this: 是每个对象中保存自身内存地址的一个引用型变量

        1.2 this能做什么

        1. 在成员变量和局部变量同名时,可以使用this来引用成员变量,来区分成员变量和局部变量

        2. 在构造方法中,可以重载调用当前对象的其他构造方法(必须在构造方法的第一行)

        3. 当需要将当前对象作为参数传递给方法或者构造方法时,return this可以做到链式调用

        1.3 this怎么用

        1.3.1 区分成员变量和局部变量

class MyClass {
	private int num;
	public void setNum(int num) {
		this.num = num; // 设置成员变量num的值
	}
}

        1.3.2 重载调用构造方法

class MyDate {
	private int year;
	private int month;
	private int day;
	
	public MyDate() {
		// 重载调用当前类的其它构造方法,this只能在构造方法的第一行
		this(1970,1,1);
		// 不影响后续代码执行
		System.out.println("无参构造");
	}
	
	// 在无参构造方法中重载调用的构造方法
	public MyDate(int year,int month,int day) {
		this.year = year;
		this.month = month;
		this.day = day;
	}
	
	//提供一个打印方法,查看结果
	public void print() {
		System.out.println(year + "年" + month + "月" + day + "日");
	}
}

public class This_01 {
	public static void main(String[] args) {
		MyDate date = new MyDate();
		date.print(); // 1970年1月1日
	}
}

        1.3.3 链式调用

public class This_02 {
	public static void main(String[] args) {
		This_02 m = new This_02();
		// 链式调用,m调用test02后,以对象的形式返回,可以继续调用test01方法
		m.test02().test01();
	}
	
	public void test01() {
		System.out.println("test01执行");
	}
	
	public This_02 test02() {
		System.out.println("test02执行");
		return this; // 将当前对象作为参数传递
	} 
}
        1.4 注意

              this不能在静态方法中调用

public class This_03 {
	public static void main(String[] args) {
		// this 不能在静态方法中调用
		// System.out.println(this);
	}
}

2. Static

        2.1 static是什么

               static是修饰符,用于区分静态和成员属性

        2.2 static能做什么

                1. 使用static修饰的变量是静态变量

                2. 使用static修饰的方法是静态方法

                3. 使用static修饰的代码块是静态代码块

public class Static_01 {
	// 静态属性
	static int id;
	
	// 静态方法
	static void m1() {	
	}
	
	// 静态语句块
	static {
		System.out.println("静态语句块");
	}
	
}
        2.3 静态语句块

                static{} 可以看作一个没有名字的方法,会在类被加载时执行,并且只能执行一次,不能复用

                程序加载时,静态语句块自动调用,在整个类的生命周期中只执行一次

                访问一个类的静态属性时,会加载该类

                静态代码块通常用于对类的静态属性进行初始化或者执行一些只需要执行一次的操作

public class Static_02 {
	static int x = 10; // 静态变量
	// 静态语句块
	// 静态加载:运行该类时,会把相关用到的所有资源全部一次性加载
	// 动态加载:运行该类时,只加载当前类,用到其它类时在加载其它类
	// java 属于动态加载
	static {
		System.out.println("静态代码块执行");
		x = 100; // 修改静态变量的值
	}
	
	public static void main(String[] args) {
		System.out.println(x); // 打印静态变量的值
	}
}

        2.4 实例语句块

                实例语句块可以看作没有名字的成员方法,只有一对{}

                实例语句块在对象创建时执行,在构造方法前执行

                实例语句块通常用于对类的实例变量进行初始化或者执行一些只需要执行一次的操作

                执行顺序:静态 -> main -> 实例 -> 构造      

          

public class Static_03 {
	private int num; // 实例变量

	static {
		System.out.println("静态语句块执行了");
	}

	{ // 实例语句块
		System.out.println("实例语句块执行");
		num = 10; // 初始化实例变量
	}

	public Static_03() { // 构造方法
		System.out.println("构造方法执行");
	}

	public static void main(String[] args) {
		System.out.println("main方法执行了");
		Static_03 t = new Static_03(); // 创建对象
		System.out.println(t.num); // 输出实例变量的值
	}

	
	/*
	 *  静态语句块执行了
	 *	main方法执行了
	 *	实例语句块执行
	 *	构造方法执行
	 *	10
	 */

}

3. 封装

        3.1 包机制        
                3.1.1 Package

                软件包机制:一种用于组织和管理类、接口和其他资源的方式,它可以将相关的类分组在一起,并通过命名空间来避免命名冲突。

                使用包机制可以提高代码的可读性、可维护性和可重用性,同时也可以控制类的访问权限,提供更好的封装性。

                package限制的是class文件的存放位置,跟Java源文件无关

                package语句必须在文件第一行

                带有package的代码因该这样编译和运行

                编译:javac -d 生成路径 java源文件路径

                        如:javac -d ./ -encoding utf-8 xxx.java

                运行:java 包名.类名

                        如:java com.Test

                3.1.2 import

                        import用于导入用到的其它类,可以使用通配符 * 来导入整个包,也可以使用静态导入来导入静态成员,

                        例如 import com.example.mypackage.*;

                        或 import static com.example.mypackage.MyClass.myStaticField;

                        该语句可以有多个,但是必须在package语句之下,class语句之上

                        如果用到的是java.lang*类,则不需要导入,因为java.lang包下为核心类

package day10_0109;
// 导入某个包下的类
import java.util.Scanner;
import com.User;
// 静态导入,这样在当前类中访问外部类就可以直接通过属性名调用了,但是不建议使用
import static com.User.name;

public class Package_01 {
	public static void main(String[] args) {
		User user = new User();
		Scanner scnner = new Scanner(System.in);
		// 核心包下的类可以直接使用
		java.lang.String s = "123";
		// 使用其它类中的静态变量,需要类名.静态变量名
		System.out.println(User.age);
		// 静态导入后,可以直接通过名字使用
		System.out.println(name);
		
	}
}
                3.1.3 注意
package day10_0109;

import java.util.Date;
//import java.sql.Date;

public class Package_02 {
	public static void main(String[] args) {
		// 一但该类存在多个并位于不同包下时,注意自动导包时不要倒错包
		Date xxxDate = new Date();
	}
}
        3.2 权限控制

JavaSE-面向对象(This, super,Static, 封装,继承,覆写)_第1张图片

        public: 公共的,可以被任何类访问,只要能找到。

        private: 私有的,只能在当前类中使用,当前类私有的,其他类无法使用

        protected: 受保护的,同包可以使用,或者是有继承关系时,通过子类使用

        default: 默认的,没有显式指定修饰符时的访问级别,可以被同包类访问

public class PPP_01 {
	public static void main(String[] args) {
		//同一包下
		A a = new A();
		System.out.println(a.a);
		System.out.println(a.b);
		//System.out.println(a.c);
		System.out.println(a.d);
		
		//不同包下
		B b = new B();
		// System.out.println(b.a);
		System.out.println(b.b);
		// System.out.println(b.c);
		// System.out.println(b.d);
	}

//与PPP_01处于同一包下
public class A {
	int a = 1;
	public int b = 2;
	private int c = 3;
	protected int d = 4;
}

// 与PPP_01处于不同包下
public class B {
	int a = 1;
	public int b = 2;
	private int c = 3;
	protected int d = 4;
}

4. 继承

        4.1 什么是继承

                继承是从已有的类中派生出新的类,新的类能够吸收已有的类的属性和方法,并且能扩展新的属性和方法

                java只支持单继承,即一个子类只能有一个直接父类,但java支持多重继承,即一个父类可以有多个子类

                Java中的继承是可以传递的,引入继承可以提高代码复用性,简化 代码结构

                当一个类没有显示继承另一个类的时候,该类默认继承java.lang.Object,Object是java提供的根类

                私有化属性不能被继承

        4.2 继承能做什么

                1.提高了代码的复用性,子类可以直接使用父类中定义的属性和方法,避免了重复编写相同的代码

                2.提高了代码的易维护性,可以使相关的类之间保持一致性,方便后续的修改和更新

                3.提高了代码的可扩展性,可以在已有功能的基础上,增加新的功能或者重写父类的方法,实现多态

        4.3 继承怎么用

                语法: class 类名 extends 父类名{}

public class Extends {
	public static void main(String[] args) {
		B b = new B();
		b.m2();
		// b调用父类方法
		b.m1();
	}
}

class C {
	public void m1() {
		System.out.println("父类方法");
	}
}
// B继承于C
class B extends C {
	public void m2() {
		System.out.println("子类方法");
	}
}

5. super    

        5.1 super是什么

              super:保存了父类特征,可以理解为父类引用对象,用于在子类中表示父类

         5.2 super能做什么

                1.在子类成员方法/构造方法中,用于区分父类与子类同名的成员变量 super.xxx

                2.在子类构造方法中,super(...)调用父类构造方法,必须在子类构造方法第一行

                如果子类构造方法中没有显示出现this()和super()的话,默认第一行有super()调用父类无参构造

                this()不能和supper()同时出现在构造方法中。

        5.3 super怎么用
                5.3.1 区分父子类同名的属性
public class SubClass extends SupClass{
	int age = 3;
	public void print() {
		//子类
		System.out.println(age);
		//子类
		System.out.println(this.age);
		//父类
		System.out.println(super.age);
	}
}

// 父类
class SupClass {
	int age = 10;
	public SupClass() {
		System.out.println("父类无参构造方法");
	}
}
                5.3.2 调用父类的构造方法
public SubClass() {
		// 默认就有super(),所以一般不写
		// 如果要写一定是调用父类的有参构造
		super();
		System.out.println("子类构造方法");
	}
        5.4 注意
public class Sup {
	// 构造方法私有化后不能在被继承
	// 因为子类构造方法中一定会调用父类构造方法,私有化后会导致子类无法访问而报错
	private Sup() {	
	}	
}

//class Sub extends Sup{
//	// 报错
//}

6. 重写/覆写

        6.1 什么是覆写

              对继承的方法进行重写编写

        6.2 应用场景

                当父类功能无法满足子类需求的时候,子类需要根据自己的需求进行功能重写

        6.2.1 重写也是有要求的

        1 必须是有继承关系的体系中

        2 方法名必须相同,返回值,参数列表 都必须相同

        3 重写的方法不能比原方法有更低的访问权限

        4 不能比原方法有更宽泛的异常

        5 覆写特指成员方法,只有成员方法可以覆写

        6.2.2 重写的目的

        1 为了满足需求

        2 错误越来越少

        3 访问权限越来越广

public class OverRide {
	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.eat();
	}
}
class Animal {
	public void eat() {
		System.out.println("动物吃东西");
	}
}

class Dog extends Animal {
	public void eat() {
		// super.eat();
		System.out.println("狗吃肉");
	}
}

6.3 @Override

class Dog extends Animal {
	// @Override 注解,源码注解,生成class文件后,就被删除了
	// 该注释只是一种检查机制,当编译时,会检查该方法是否符合方法覆写的要求
	// 如果不符合方法覆写,则会报错提醒,所以这个注解是一种检查提醒机制
	// 防止程序员因粗心导致的错误
	@Override
	public void eat() {
		// super.eat();
		System.out.println("狗吃肉");
	}
}

你可能感兴趣的:(java,数据结构,jvm)