一、static关键字
1.1含义
静态方法属于类的方法,直接使用类名调用
1.2应用场景
工具类
什么情况下把方法变作为静态方法?
纯功能的方法,就可以设置为静态方法
package com.qf.arrays;
public class MyArrays {
/**
* 数组的排序
* @param is 需要排序的数组
*/
public static void sort(int[] is){
for (int i = 0; i < is.length-1; i++) {
for (int j = 0; j < is.length-1-i; j++) {
if(is[j] > is[j+1]){
int temp = is[j];
is[j] = is[j+1];
is[j+1] = temp;
}
}
}
}
/**
* 替换数组
* @param is 要替换的数组
* @param val 替换的值
*/
public static void fill(int[] is, int val){
for (int i = 0; i < is.length; i++) {
is[i] = val;
}
}
/**
* 替换数组
* @param is 要替换的数组
* @param start 开始下标(包含)
* @param end 结束下标(不包含)
* @param val 替换的值
*/
public static void fill(int[] is,int start, int end, int val){
for (int i = start; i < end; i++) {
is[i] = val;
}
}
/**
* 拷贝数组
* @param is 要拷贝的数组
* @param newLength 新数组的长度
* @return 新数组
*/
public static int[] copyOf(int[] is, int newLength){
int[] newIs = new int[newLength];
for (int i = 0; i < is.length; i++) {
newIs[i] = is[i];
}
return newIs;
}
/**
* 获取数组的字符串表示
* @param is 目标数组
* @return 数组的字符串表示
*/
public static String toString(int[] is){
String str = "[";
for (int i = 0; i < is.length; i++) {
str += is[i];
if(i != is.length-1){//不是最后一个元素就加逗号
str += ",";
}
}
str += "]";
return str;
}
}
package com.qf.test01;
import com.qf.arrays.MyArrays;
public class Test01 {
public static void main(String[] args) {
int[] is = {4,3,5,2,1};
MyArrays.sort(is);
int[] copyOf = MyArrays.copyOf(is, 10);
MyArrays.fill(copyOf, 888);
MyArrays.fill(copyOf, 2, 5, 666);
System.out.println(MyArrays.toString(copyOf));
}
}
1.3 static - 静态代码块
静态代码块是类加载到方法区时才会被调用,该代码块只能初始化静态变量
代码块是创建对象时优先于构造方法调用,该代码块可以初始化成员变量和静态变量
构造方法是创建对象时调用,该方法可以初始化成员变量和静态变量
package com.qf.test02;
public class A {
//成员变量
String str1;
//静态变量
static String str2;
//静态代码块
//注意:类加载到方法区时,调用静态代码块
//注意:静态代码只能初始化静态方法
static{
str2 = "ccc";//底层:A.str2
System.out.println("静态代码块 " + str2);
}
//代码块
//注意:创建对象时优先于构造方法调用
//注意:代码块可以初始化成员变量和静态方法
{
str1 = "bbb";//底层:this.str1
str2 = "bbb";//底层:A.str2
System.out.println("代码块 " + str1 + " -- " + str2);
}
//注意:构造方法可以初始化成员变量和静态变量
public A(){
str1 = "aaa";//底层:this.str1
str2 = "ddd";//底层:A.str2
System.out.println("A类的构造方法 " + str1 + " -- " + str2);
}
}
package com.qf.test02;
public class Test01 {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
}
}
二、继承
2.1含义
子类继承父类的属性和方法
2.2应用场景
需求中要求编写多个类,分析时发现多个类有共同的属性和方法,就可以把这些共同的属性和方法抽取出,放在父类里
好处:解决代码的冗余
2.3需求
编写中国人类和日本人类,然后操作对象
2.3.1分析
人类:
属性:姓名、性别、年龄
方法:吃饭饭、睡觉觉
中国人类 继承 人类:
属性:身份证
方法:打太极
日本人类 继承 人类:
属性:年号
方法:拍电影
2.3.2父类
package com.qf.test03;
public class Person {
String name;
char sex;
int age;
public void eat(){
System.out.println("吃饭饭");
}
public void sleep(){
System.out.println("睡觉觉");
}
}
2.3.3子类
package com.qf.test03;
// 子类 继承 父类
public class Chinese extends Person{
String id;
public void playTaiJi(){
System.out.println("打太极");
}
}
package com.qf.test03;
// 子类 继承 父类
public class Japanese extends Person {
String yearNum;
public void playVedio(){
System.out.println("拍电影");
}
}
2.3.4测试类
package com.qf.test03;
public class Test01 {
public static void main(String[] args) {
Chinese c = new Chinese();
//设置父类成员变量
c.name = "李伟杰";
c.sex = '男';
c.age = 18;
//获取父类成员变量
System.out.println(c.name);
System.out.println(c.sex);
System.out.println(c.age);
//调用父类成员方法
c.eat();
c.sleep();
//设置子类成员变量
c.id = "1234567890";
//获取子类成员变量
System.out.println(c.id);
//调用子类成员方法
c.playTaiJi();
System.out.println("---------------");
Japanese j = new Japanese();
//设置父类成员变量
j.name = "波多野结衣";
j.sex = '女';
j.age = 16;
//获取父类成员变量
System.out.println(j.name);
System.out.println(j.sex);
System.out.println(j.age);
//调用父类成员方法
j.eat();
j.sleep();
//设置子类成员变量
j.yearNum = "昭和";
//获取子类成员变量
System.out.println(j.yearNum);
//调用子类成员方法
j.playVedio();
}
}
三、深入继承
3.1知识点
知识点:深入继承
1.创建子类对象时,是否调用父类构造方法?
会调用
2.创建子类对象时,是否创建父类对象?
不会
3.创建子类对象时,调用父类构造方法的目的是什么?
目的是:子类对象在堆中开辟的空间内再划分区域,专门存放父类的成员变量
4.创建子类对象时,先调用父类构造方法还是子类构造方法?
先调用子类构造方法
5.创建子类对象时,先完成父类构造方法还是子类构造方法?
先完成父类构造方法
6.子类可以继承父类的私有化成员变量和私有化成员方法吗?
可以,但不能直接调用,可以间接调用
总结:
子类继承父类所有的属性和方法
3.1.1父类对象
package com.qf.test04;
public class Father {
private String fatherAttr = "父类私有化成员变量";
public Father(){
System.out.println("父类的构造方法");
}
private void fatherMethod01() {
System.out.println("父类私有化成员方法");
}
public void fatherMethod02(){
System.out.println(fatherAttr);
fatherMethod01();
}
}
package com.qf.test04;
public class Son extends Father{
public Son(){
//super(); 默认实现:调用父类的无参构造
System.out.println("子类的构造方法");
}
}
3.1.2测试类
package com.qf.test04;
public class Test01 {
public static void main(String[] args) {
Son son = new Son();
//间接调用父类的私有化成员变量和成员方法
son.fatherMethod02();
}
}
四、super关键字
4.1作用
1.super.属性:在子类中调用父类非私有化的成员变量
2.super.方法:在子类中调用父类非私有化的成员方法
3.super():在子类中调用父类非私有化的构造方法
4.2需求
编写中国人类和日本人类,然后操作对象
4.3分析
人类:
属性:姓名、性别、年龄
方法:吃饭饭、睡觉觉
中国人类 继承 人类:
属性:身份证
方法:打太极日本人类 继承 人类:
属性:年号
方法:拍电影
4.3.1父类
package com.qf.test05;
public class Person{
private String name;
private char sex;
private int age;
public Person() {
}
public Person(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(){
System.out.println("吃饭饭");
}
public void sleep(){
System.out.println("睡觉觉");
}
}
4.3.2子类
package com.qf.test05;
public class Chinese extends Person{
private String id;
public Chinese() {
}
public Chinese(String name, char sex, int age, String id) {
super(name, sex, age);
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void playTaiJi(){
System.out.println(super.getName() + "打太极");
}
}
package com.qf.test05;
public class Japanese extends Person {
private String yearNum;
public Japanese() {
}
public Japanese(String name, char sex, int age, String yearNum) {
super(name, sex, age);
this.yearNum = yearNum;
}
public String getYearNum() {
return yearNum;
}
public void setYearNum(String yearNum) {
this.yearNum = yearNum;
}
public void playVedio(){
System.out.println(super.getName() + "拍电影");
}
}
4.3.3测试类
package com.qf.test05;
public class Test01 {
public static void main(String[] args) {
Chinese c = new Chinese("张三", '男', 18, "1234567890");
//调用父类成员方法
System.out.println(c.getName());
System.out.println(c.getSex());
System.out.println(c.getAge());
c.eat();
c.sleep();
//调用子类成员方法
System.out.println(c.getId());
c.playTaiJi();
System.out.println("---------------");
Japanese j = new Japanese("波多野结衣", '女', 16, "昭和");
//调用父类成员方法
System.out.println(j.getName());
System.out.println(j.getSex());
System.out.println(j.getAge());
j.eat();
j.sleep();
//调用子类成员方法
System.out.println(j.getYearNum());
j.playVedio();
}
}
五、重写
5.1含义
父类方法在子类重新写一遍
5.2应用场景
父类方法不可改变时,并且父类方法不满足子类需求时,考虑在子类中重新写一遍
条件:
1.在子类中重写父类的成员方法
2.返回值、方法名、参数列表必须和父类重写的方法一致
3.访问修饰符不能被父类重写的方法更严格
5.3需求
编写人类、中国人类、日本人类,然后操作对象
5.4分析
人类:
属性:姓名、性别、年龄
方法:吃饭饭、睡觉觉
中国人类 继承 人类:
属性:身份证
方法:打太极日本人类 继承 人类:
属性:年号
方法:拍电影
需求的场景:联合开发(比如:人类-李伟杰,中国人类和日本人类-张三)
5.4.1父类
package com.qf.test06;
public class Person{
private String name;
private char sex;
private int age;
public Person() {
}
public Person(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat(){
System.out.println(this.name + "吃饭饭");
}
public void sleep(){
System.out.println(this.name + "睡觉觉");
}
}
5.4.2子类
package com.qf.test06;
public class Chinese extends Person{
private String id;
public Chinese() {
}
public Chinese(String name, char sex, int age, String id) {
super(name, sex, age);
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void playTaiJi(){
System.out.println(super.getName() + "打太极");
}
//注解:类似于注释
//注释的作用:向程序员解释代码信息
//注解的作用:向程序员和系统解释代码信息
//@Override -- 该注解表示重写父类的方法
@Override
public void eat(){
System.out.println(super.getName() + "吃山珍海味");
}
}
package com.qf.test06;
public class Japanese extends Person {
private String yearNum;
public Japanese() {
}
public Japanese(String name, char sex, int age, String yearNum) {
super(name, sex, age);
this.yearNum = yearNum;
}
public String getYearNum() {
return yearNum;
}
public void setYearNum(String yearNum) {
this.yearNum = yearNum;
}
public void playVedio(){
System.out.println(super.getName() + "拍电影");
}
//注解:类似于注释
//注释的作用:向程序员解释代码信息
//注解的作用:向程序员和系统解释代码信息
//@Override -- 该注解表示重写父类的方法
@Override
public void eat() {
System.out.println(super.getName() + "吃马赛克");
}
}
5.4.3测试类
package com.qf.test06;
public class Test01 {
public static void main(String[] args) {
Chinese c = new Chinese("李伟杰", '男', 18, "1234567890");
c.eat();
System.out.println("---------------");
Japanese j = new Japanese("波多野结衣", '女', 16, "昭和");
j.eat();
}
}
六、访问修饰符
6.1含义
修饰类、方法、属性
注意:只能使用默认的和public修饰类
作用:定义使用的范围
访问修饰符 | 本类 | 本包 | 其他子包 | 其他包 |
private | ok | |||
默认的 | ok | ok | ||
protected | ok | ok | ok | |
public | ok | ok | ok | ok |
6.2经验
1.属性一般使用private修饰
2.方法一般使用public修饰
3.如果该方法不想让外界使用,使用private修饰
4.如果该方法只想让子类使用,使用protected修饰
package com.qf.test07;
public class A {
public String str = "A类的属性";
public void method01(){
System.out.println(this.str);
}
}
package com.qf.test07;
public class Test01 {
public static void main(String[] args) {
A a = new A();
System.out.println(a.str);
}
}
package com.qf.test08;
import com.qf.test07.A;
public class B extends A{
public void xxx(){
System.out.println(super.str);
}
}
package com.qf.test08;
import com.qf.test07.A;
public class Test01 {
public static void main(String[] args) {
/**
* 访问修饰符做实验
*/
A a = new A();
System.out.println(a.str);
}
}