2021-03-31

这篇博客深入探讨了面向对象编程中的关键概念,包括this关键字的用法,如区分成员变量和局部变量、链式调用、构造方法中的应用;static修饰符的作用,如静态变量、静态方法和静态语句块;封装的概念及其实现,如权限修饰符的应用;以及继承的概念和使用,包括方法覆写和super关键字的使用。文章通过实例代码详细解释了这些概念,并提供了相关练习题以巩固理解。
摘要由CSDN通过智能技术生成

Day08 static、this、封装、继承

  1. 面向对象
    1 上课了解是什么,解决那些问题,应用场景,语法
    2 写上课案例代码(1 熟悉语法 2 知道到底怎么用 3 改代码,运行,和预期结果对比)
    3 练习题,应用知识,举一反三,碰到问题,解决问题
    4 总结
    1.1 传值和传引用

注意 : 传引用,传递的是地址,如果地址传递到另一个地方,则拥有相同地址的变量,可以找到同一个对象,那么操作的数据也是相互的

1.2 This
1.2.1 是什么
this是每个对象中,保存当前内存地址的一个引用类型变量
所以说,this就表示当前对象自己, 相当于我们说 “我” 一样
谁调用的当前方法,this就是谁
1.2.2 能干什么
1 在成员方法或者构造方法中,用来区分同名的局部变量和成员变量
2 this不能出现在静态环境下
3 return this ; 返回当前对象的内存地址,可以做到链式调用
4 用在构造方法中,调用当前类中重载的构造方法 this(xxx),但必须在第一行
1.2.3 怎么用
1.2.3.1 区分成员变量和局部变量
class B{
private int age;
public void setAge(int age){
this.age = age;
}
public void setAge1(int _age){
age = _age;
}
}
1.2.3.2 不能出现在静态上下文中
不能出现如下情况:
System.out.printl(this);

1.2.3.3 链式调用
public class This_02 {

public static void main(String[] args) {
	C c = new C();
	c.m1();
	c.m2();
	c.m1().m2();
	int i = c.xxx();

	c.m1().m2();
}

}

class C {
public int xxx() {
return 1;
}

public C m1() {
	System.out.println("我是m1");
	m2();
	this.m2();
	return this;
}

public void m2() {
	System.out.println("我是m2");
}

}
1.2.3.4 调用重载的构造方法

this 用在构造方法中,还可以重载调用当前类中其他构造方法
语法 : this(参数); 必须在构造方法第一行

案例:
package _01_this;

/**
*

  • @author GeneralHuge

  • @Date 2021年3月31日
    */
    public class This_03_1 {

    public static void main(String[] args) {
    // MyDate d1 = new MyDate();
    // d1.year = 2021;
    // d1.month = 3;
    // d1.day = 21;
    // d1.println();

     // MyDate d2 = new MyDate();
     // 如果不赋值,就是 0年0月0日
     // d2.println();
    
     // 需求 : 必须有年月日
     MyDate d3 = new MyDate(2021, 3, 21);
     d3.println();
    
     // 此时 不传递参数 就会报错,因为没有无参构造
     // MyDate d4 = new MyDate();
    
     // 需求 : 如果不传递年月日 则 默认为 1970年1月1日
     MyDate d5 = new MyDate();
     d5.println();
    

    }
    }

class MyDate {
int year;
int month;
int day;

public MyDate() {
	// this.year = 1970;
	// this.month = 1;
	// this.day = 1;
	// 上面代码重复编写,可以直接调用重载的构造方法来解决
	this(1970, 1, 1);
}

public  MyDate(int year, int month, int day) {
	this.year = year;
	this.month = month;
	this.day = day;
}

public void println() {
	System.out.println(year + "年" + month + "月" + day + "日");
}

}

1.3 Static
1.3.1 是什么
static 是一个修饰符,用来区别静态和成员属性
1.3.2 能干什么
1 static修饰的类体中的变量是静态变量
2 static修饰的类体中的方法是静态方法
3 static修饰的语句块是静态语句块

静态属性是在类加载阶段执行初始化的
什么时候类加载?
访问一个类的静态属性的时候,把该类载入静态区
1.3.3 怎么用
1.3.3.1 静态变量和静态方法
代码如下:
public class Static_01 {
static int i = 2;
public static void m1(){}

1.3.3.2 静态语句块
// 静态语句块等价于 静态方法 ,只不过 它没有名字,不能重复执行
// 自动执行,并且只执行一次,类加载完直接执行,在main方法被调用之前执行
// 多个静态语句块 按照从上往下执行
示例代码如下:
static{
System.out.println(“静态语句块1”);
System.out.println(i);
}

public static void m1(){}
public static void main(String[] args) {
	System.out.println("main");
}
static{
	System.out.println("静态语句块2");
}

1.3.3.3 动态语句块

实例语句块语法
{
java代码;
}
等价于 成员方法
而成员属性依赖对象
创建对象之后立刻执行,并且每创建一个对象就执行一次

案例代码如下:
public class Static_02 {
int age;

public Static_02(int age) {
	this.age = age;
	System.out.println("构造方法");
}

{
	System.out.println("实例语句块1");
}
{
	System.out.println("实例语句块2");
}

public static void main(String[] args) {
	Static_02 s = new Static_02(18);
	System.out.println(s);
	new Static_02(22);
}

}
1.3.3.4 静态属性调用
代码如下:
public class Static_03 {

public static void main(String[] args) {
	System.out.println(E.age);
	E e1 = new E();
	E e2 = new E();
	System.out.println(e1.age);
	System.out.println(e2.age);
	// 只要更改静态的值
	e1.age= 2;
	// 所有对象访问都是更改之后的
	System.out.println(E.age);
	System.out.println(e1.age);
	System.out.println(e2.age);
	// 赋值为null
	// 空指针 : 使用null值调用 成员属性,报空指针异常
	e1 = null;
	// 而 age 是静态属性,对象无关,有没有堆内存对象压根无所谓,只要这个变量是E 类型的,就能调用静态属性
	System.out.println(e1.age);
}

}
class E{
static int age;
}
1.3.3.5 静态和成员的区别
静态是所有对象共享
成员是所有对象独立(不共享)
如果对象有相同的属性不同的值,使用成员变量
如果对象有相同的属性相同的值,使用静态变量
1.4 封装
封装 就是把对象的所有组成部分组合在一起,使用权限修饰符将数据隐藏起来
控制用户对数据的不合理操作
作用 : 适当的封装可以让代码更容易理解和维护,也加强了代码的安全性
1.4.1 软件包机制
1.4.1.1 Package
软件包机制目标 : 文件的编译和运行
文件名 : 找到这个文件的全路径就是文件名,
1 为了解决命名冲突问题(在类名之前,加前缀,package)
2 java中使用package语句定义包
3 package规定class文件的保存位置(并不是.java源文件)
4 package语句 只能出现在java文件的第一行
5 package命名规则 一般采用公司域名倒序.项目.模块 com.tledu.oa.system; 是天亮公司开发的OA系统,当前是system模块
6 完整的类名,是带有包名
7 带有package语句的java文件编译
javac -d 生成路径 -encoding 编码 源文件路径
javac -d ./ -encoding utf-8 A.java
8 带有package语句的class文件运行
java 包名.类名
java com.tledu.zrz.A
1.4.1.2 Import
import语句 : 用于引入当前类中需要的其他包中的类
import语句,只能在class语句之上,package语句之下
java.lang.* 下面的所有类 ,使用不需要导入,因为java.lang是核心包
可以使用 java.util.* ; 来导入 对应包下的所有类
可以使用 java.util.Date; 来导入指定的类

代码如下
public static void main(String[] args) {
// 如果使用的类和当前类在同包下,可以直接写名字使用
Package_01 p1 = new Package_01();

	// 比如我们要使用User , 而 User的package是 _05_package.model
	// 所以 想要找到User,必须写全名(包名.类名)
	_05_package.model.User user = new _05_package.model.User();
	System.out.println(user.i);
	
	// 上面代码比较麻烦,也不美观,所以可以通过 import语句导入
	User user1 = new User();
	System.out.println(user1.i);
}

导入静态包代码如下:
import _03_package.model.User;
// 静态导入 User类中的静态属性,可以再当前类中直接写名字使用
import static _03_package.model.User.*;
public class Package_03 {

public static void main(String[] args) {
	// 使用其他类中 的静态属性,需要加类名
	// System.out.println(age);
	System.out.println(User.age);
	System.out.println(age);
	m1();
}

}
1.4.1.3 注意
编写代码时,当我们按空格 或者是 回车的时候,会自动导包,需要注意,是否导入的正确

1.4.2 权限修饰
规定一个数据的访问范围

private : 除了当前类,其他地方都不能访问
public : 哪里都能访问
default : 不写权限修饰符,默认为default,当前类或者是当前包下可以访问
protected : 受保护的,继承权限,如果没有继承关系,同包也是可以访问的
要么有继承关系,要么同包,继承需要通过子类对象访问

代码如下:
public static void main(String[] args) {
// 私有 不能访问
// System.out.println(A.a);
// 公共 可以访问
System.out.println(A.b);
// 默认,但是同包,可以访问
System.out.println(A.c);
// protected 同包也可以访问
System.out.println(A.d);

	// 私有 不能访问
	// System.out.println(B.a);
	// 公共 能访问
	System.out.println(B.b);
	// 默认,不同包,不能访问
	// System.out.println(B.c);
	// protected 不同包 不能访问
	// System.out.println(B.d);

	// 有继承关系后,通过子类对象,访问protected属性
	PPP_01 p = new PPP_01();
	System.out.println(p.d);
	
}

1.5 继承extends
1.5.1 是什么
Java中只支持单继承,不支持多继承,这样使继承关系比较简单,一个类 只有一个父类,易于程序管理,当然为了解决单继承功能变弱的问题,java又提出了接口,一个类可以实现N个接口
如果一个类,没有显示继承几个父类的话,则该类默认继承java.lang.Object
不管如何继承,最终任何类都直接/间接的成为Object的子类
Object是java提供的根类(祖宗)
Private不能被继承,但是可以通过getter/setter对私有属性进行操作
构造方法不能被继承

目的 : 代码重用
最大的功能扩展 : 方法覆写

1.5.2 能干什么
1 代码重用,父类进行编码之后,子类可以直接使用
2 如果父类的功能不能满足子类需求,还可以对功能进行重写
3 使用多态
1.5.3 怎么用
class 子类名 extends 父类名{
}

代码如下:
SubClass.java文件
public class SubClass extends SupClass {
public void m3() {
System.out.println(“子类的成员方法”);
}
}
SupClass.java文件
public class SupClass {
private int i = 2;

public int getI() {
	return i;
}

public void setI(int i) {
	this.i = i;
}

public static void m1() {
	System.out.println("父类的m1");
}

public void m2() {
	System.out.println("父类的m2");
}

}
Main方法:
public static void main(String[] args) {
// 因为有继承关系,所以可以直接通过子类访问父类的属性和方法
SubClass sub = new SubClass();
sub.m2();
sub.m1();
sub.m3();
System.out.println(sub.getI());
}

1.6 Super
1.6.1 是什么
表示父类型特征,不是父类对象引用
This表示当前对象引用

1.6.2 能干什么
1 用在成员方法和构造方法中 可以通过super去访问父类的属性
可以通过super区别子类和父类同名的属性
2 super不能出现在静态上下文中,尽管在成员方法/构造方法中,也必须是 super.xxx 的形式
3 用在子类构造方法中,使用super(xxx) 去调用父类的构造方法
如果子类构造方法中没有显示定义 this(xxx) / super(xxx) 则 默认第一行有个 super() 调用父类的无参构造
并且 this(xxx) 和 super(xxx) 这种写法,都必须出现在构造方法第一行,所以这两种写法不能同时存在
1.6.3 怎么用
1.6.3.1 区分父类和子类相同的属性
public class SubClass extends SupClass {
int age = 20;

public void m1() {
	// 因为父子类中age同名,所以直接使用age 会调用子类
	System.out.println(age);
	// 可以通过super. 来区分父子类同名的属性
	System.out.println(super.age);
	// 如果父类和子类没有通过,可以直接写父类的名字即可
	System.out.println(name);
	m2();
	super.m2();
}

public void m2() {
	// 成员方法中, super必须 . 的形式访问
	// System.out.println(super);
	System.out.println(super.age);
	System.out.println("我是子类的m2");
}

public static void m4() {
	// 静态方法中 压根不能使用
	// System.out.println(super.age);
}

}

类名 : 区分同名的局部变量和静态变量
This : 区分同名的局部变量和成员变量
Super : 区分父子类中同名的变量和方法

1.6.3.2 Super注意事项
具体代码如下:
public void m2() {
// 成员方法中, super必须 . 的形式访问
// System.out.println(super);
System.out.println(super.age);
System.out.println(“我是子类的m2”);
}

public static void m4() {
	// 静态方法中 压根不能使用
	// System.out.println(super.age);
}

}

1.6.3.3 调用父类的构造方法

案例代码如下:
public class Sub extends Sup {
static {
System.out.println(“子类静态语句块”);
}
{
System.out.println(“子类实例语句块”);
}

public Sub() {
	// 就算不写super() 也会默认有一个去调用父类的无参构造
	super(2);
	System.out.println("子类构造方法");
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值