目录
一、static静态关键字
二、static应用知识:工具类
三、static应用知识:代码块
四、static应用知识:单例
五、面向对象三大特征之二:继承
static是计算机高级语言关键字
像在VB,C#,C,C++,Java,PHP,Objective-C,JavaScript中我们可以看到static作为关键字和函数出现,在其他的高级计算机语言如FORTRAN、ALGOL、COBOL、BASIC、LISP、SNOBOL、PL/1、Pascal、PROLOG、Ada等语言中也是有出现的,只是有着不同的作用,对于其具体作用,有需要的时候是可以具体查阅的。
1.static是什么?修饰成员变量的用法?
①static是静态的意思,可以修饰成员变量和成员方法。
②static修饰成员变量表示该成员变量只在内存中只存储一份,可以被共享访问、修改。
2.成员变量可以分为2类。
①静态成员变量(有static修饰,属于类,内存中加载一次):常表示如在线人数信息、等需要被共享信息,可以被共享访问。
访问格式:
类名.静态成员变量。(推荐)
对象.静态成员变量。(不推荐)
②实例成员变量(无static修饰,存在于每个对象中):长表示姓名name、年龄age、等属于每个对象的信息。
访问格式:
对象.实例成员变量
代码演示:
//类的五大成分(成员变量、成员方法、工具类、代码块、内部类)
public class Demo1 {
//相同包下的类可以直接访问,不同包下的类必须导包,才可以使用! 导包的语法格式:import 包名.类名;
public static void main(String[] args) {
//static修饰成员变量的作用和访问特点
//1.类名。静态1成员变量
System.out.println(user.onlineNumber);//161
user u = new user();
u.onlineNumber++;//新增一个人
System.out.println(u.onlineNumber);
//注意:如果这个类中使用不同包下的相同的类名,此时默认只能导入一个类的包,另一个类则要使用全名访问。
//权限修饰符:控制一个成员能够被访问的范围 : 可以修饰成员变量,方法,构造器,内部类。
}
}
3.两种成员变量各自在什么情况下定义?
①静态成员变量:表示在线人数等需要被共享的信息。
②实例成员变量:属于每个对象,且每个对象的该信息不同时(如:name、age、money.......等)。
4.每种成员方法的使用场景是怎么样的?
①表示对象自己的行为的,且方法中需要直接访问实例成员,则该方法必须申明成实例方法。
②如果该方法是以执行一个通用功能为目的,或者需要方便访问,则可以申明成静态方法。
5.static修饰成员方法的基本用法
代码演示:
import ArrayList.Student;
/**
* 成员方法的分类
* 静态成员变量(方法)(有static修饰,归属于类),建议用类名访问,也可以用对象访问 通用的功能 属于类
* 实例成员方法(变量)(无static修饰,归属于对象),只能用对象触发访问 自己的方法 属于对象
*/
public class static_Demo2 {
/**
* 实例成员变量,无static修饰,属于对象
*/
private String name;
public static int getmax(int age1 ,int age2) {
return age1>age2 ? age1:age2;
}
/**
* 实例方法:属于对象的,只能用对象触发访问
*/
public void student(){
System.out.println(name + "好好学习,天天向上");
}
public static void main(String[] args) {
//1.类名,静态方法变量
System.out.println(static_Demo2.getmax(10,3));
//2.注意:同一个类中,访问静态方法,类名可以省略不写
System.out.println(getmax(10, 32));
Student s = new Student(13, "吴磊", 34, "卓越一班");
//3.对象调用静态方法(语法可行,但不推荐)
System.out.println(s.getAge());
}
}
6.static修饰成员方法的内存原理
7.static的注意事项
①静态方法只能访问静态的成员,不可以直接访问实例成员。
②实例方法可以访问静态成员,也可以访问实例成员。
③静态方法中是不可以出现this关键字的。
import ArrayList.Student;
/**
* 成员方法的分类
* 静态成员变量(方法)(有static修饰,归属于类),建议用类名访问,也可以用对象访问 通用的功能 属于类
* 实例成员方法(变量)(无static修饰,归属于对象),只能用对象触发访问 自己的方法 属于对象
*/
public class static_Demo2 {
/**
* 实例成员变量,无static修饰,属于对象
*/
private String name;
public static int getmax(int age1 ,int age2) {
return age1>age2 ? age1:age2;
}
/**
* 实例方法:属于对象的,只能用对象触发访问
*/
public void student(){
System.out.println(name + "好好学习,天天向上");
}
public static void main(String[] args) {
//1.类名,静态方法变量
System.out.println(static_Demo2.getmax(10,3));
//2.注意:同一个类中,访问静态方法,类名可以省略不写
System.out.println(getmax(10, 32));
Student s = new Student(13, "吴磊", 34, "卓越一班");
//3.对象调用静态方法(语法可行,但不推荐)
System.out.println(s.getAge());
}
/**
* 1.静态方法只能访问静态的成员,不可以直接访问实例成员
* 2.实例方法可以访问静态成员,也可以访问实例成员
* 3.静态方法中不可出现this关键字
*/
/**
* 静态成员
*/
public static int onlineNumber = 10;
public static void test(){
System.out.println("=====test======");
}
/**
* 实例成员
*/
private String name2;
public void run(){
System.out.println(name2+"跑得快~");
}
//1.静态方法只能访问静态的成员,不可以直接访问实例成员
public static void test1(){
System.out.println(static_Demo2.onlineNumber);
System.out.println(onlineNumber);
test();
static_Demo2 t = new static_Demo2();
System.out.println(t.name2);//不能直接访问,间接访问
}
//2.实例方法可以访问静态成员,也可以访问实例成员
public void go(){
System.out.println(static_Demo2.onlineNumber);
System.out.println(onlineNumber);
test();
System.out.println(name2);
System.out.println(this);//this可以出现在实例方法中
run();
}
//3.静态方法中不可出现this关键字
public static void test3(){
//System.out.println(this);this只能代表当前对象
}
}
1.工具类是什么?
类中都是一些静态方法,每个方法都是以完成一个公用的功能为目的,这个类用来给系统开发人员共同使用的。
2.例题: 验证码工具类
工具类:
import java.util.Random;
/**
* 工具类
*/
public class static_login {
/**
* 由于工具类无法创建对象,所以把其构造器私有化会显得很专业
*/
private static_login(){
}
/**
* 静态方法
*/
public static String createVerifyCode(int n) {
//1.定义一个变量记住验证码
String code = " ";
//2.定义一个变量记住全部验证码字符
String data = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPSADFGHJKLZXCVBNM1234567890";
//3.定义一个循环生成几个随即索引,去获取字符
Random r = new Random();
for (int i = 0; i < n; i++) {
//4.获取随即索引的对应字符。链接给code
int index = r.nextInt(data.length());
code +=data.charAt(index);
}
return code;
}
}
实现类:
public class login {
public static void main(String[] args) {
System.out.println(static_login.createVerifyCode(5));
}
}
3.为什么工具类中的方法不用实例方法做?
①实例方法需要创建对象调用;
②此时用对象只是为了调用方法,这样只会浪费内存。
4.工具类定义时的其他要求:
由于工具里面都是静态方法,直接用类名即可访问,因此,工具类无需创建对象,建议将工具类的构造器进行私有。
5.工具类是什么,有什么好处?
①内部都是一些静态方法,每个方法完成一个功能;
②一次编写,处处可用,提高代码的复用性;
6.工具类有什么要求?
建议工具类的构造器私有化处理
1.代码块概述:
①代码块是类的5大成分之一(成员变量、构造器、方法、代码块、内部类),定义在类中方法外。
②在java类下,使用{}括起来的代码被称为代码块。
2.代码块分类:
①静态代码块
格式: static{}
特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次。
使用场景:在类加载的时候做一些静态数据初始化的操作,以便后续使用。
②构造代码块
格式: {}
特点:每次创建对象,调用构造器执行时,都会执行该代码块中的代码,并在构造器执行前执行。
使用场景:初始化实例资源。
代码演示:
public class static_Demo {
/**
* 代码块:在Java类下 :使用{}括起来的代码被称为代码块
*/
/**
* 静态代码块:static{} 初始化静态资源
* 特点: 需要通过static关键字修饰,随着类的加载而加载,并自动触发,只执行一次
* 使用场景:在类加载的时候做一些静态数据初始化的操作,以便后续使用,(用于在程序启动时,进行静态资源的初始化操作)
*/
/**
* 构造代码块{}
* 特点:每次创建对象,调用构造器执行时,都会执行该代码块中的代码,并且在构造器执行前执行
* 使用场景:初始化实例资源
*/
private String name;
static {
System.out.println("==================静态代码块被触发执行了=========");
}
public static_Demo3(){
System.out.println("========无参构造器被触发==============");
}
{
name = "张三";
System.out.println("========实例(构造)代码块被触发执行================");
}
public static void main(String[] args) {
System.out.println("main方法执行");
static_Demo3 s1 = new static_Demo3();
System.out.println(s1.name);
static_Demo3 s2 = new static_Demo3();
System.out.println(s2.name);
}
}
1.什么是设计模式(Design pattern)
①开发中经常遇到一些问题,一个问题通常有n种解法的,但其中肯定有一种解法是最优的,这个最优的解法被人总结出来,称之为设计模式。
②设计模式有20多种,对应20多种软件开发中遇到的问题。
2.学设计模式主要是学2点
第一:这种模式用来解决什么问题。
第二:遇到这种问题了,该模式是怎么写的,他是如何解决这个问题的。
3.单例模式
①可以保证系统中,应用该模式的这个类永远只有一个实例,即一个类永远只能创建一个对象。
②例如任务管理器对象我们只需要一个就可以解决问题了,这样可以节省内存空间。
4.单例的实现方式很多
①饿汉单例模式
②懒汉单例模式
.......
5.饿汉单例设计模式
在用类获取对象的时候,对象已经提前为你创建好了
设计步骤:
①定义一个类,把构造器私有;
②定义一个静态变量存储一个对象。
代码演示:
单例类:
/**
* 使用饿汉单例实现单例类
*/
public class singleIntstance {
/**
* 2.饿汉单例是在获取对象前,对象已经提前准备好一个,这个对象只能是一个,所以定义静态成员变量记住
*/
public static singleIntstance instance = new singleIntstance();
/**
* 把构造器私有化
*/
private singleIntstance(){
System.out.println("创建了一个饿汉单例对象");
}
}
实现单例类:
public class Test {
public static void main(String[] args) {
//饿汉单例
singleIntstance s1 = singleIntstance.instance;
singleIntstance s2 = singleIntstance.instance;
System.out.println(s1==s2);
}
}
6.懒汉单例设计模式
在真正需要该对象的时候,才去创建一个对象(延迟加载对象)。
设计步骤:
①定义一个类,把构造器私有;
②定义一个静态变量存储一个对象。
③提供一个返回单例对象的方法。
代码演示:
单例类:
public class singleIntstance {
/**
* 懒汉单例:在真正需要该对象时,才去创建一个对象(延迟加载对象)
*/
//第一次拿对象:此时需要创建对象
/**
* 2、定义一个静态的成员变量负责存储一个对象,只加载一次,只有一份
*/
private static singleIntstance instance;
/**
* 3、提供一个方法,对外返回单例对象
*/
public static singleIntstance getInstance(){
if (instance == null) {
//第一次来拿对象
instance = new singleIntstance();
}
return instance;
}
/**
* 1、构造器私有化
*/
public singleIntstance(){
System.out.println("");
}
}
实现单例类:
public class singlelntstance_Test {
public static void main(String[] args) {
//懒汉单例
singleIntstance s1 = singleIntstance.getInstance();
singleIntstance s2= singleIntstance.getInstance();
System.out.println(s1);
System.out.println(s2);
System.out.println(s1==s2);
}
}
1.什么是继承?
java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起父子关系。
public class Student extends people{}
Student称为子类(派生类),people称为父类(基类或超类)。
父类(super)、子类(this)
作用:当子类继承父类后,就可以直接使用父类公共的属性和方法了。
2.继承规范:
①子类们相同特征(共性属性,共性方法)放在父类中定义。
②子类独有的属性和行为应该定义在子类自己里面。
3.继承的特点:
①子类有自己的构造器,不能继承父类的构造器。
②子类是否可以继承父类的私有成员(可以继承父类的私有成员,只是不能直接访问! )。
③子类是否可以继承父类的静态成员(不是继承,是共享的父类的) 。
④java只能继承一个父类,不支持多继承,不过支持多层继承。 多层继承: A继承B,B继承C;
⑤object :object是祖宗类
4.在子类中给访问成员(成员变量、成员方法)满足:就近原则(局域对象<子类对象<父类对象)
①先子类局部范围找。
②然后子类成员范围找。
③然后父类成员范围找,如果父类范围还没有找到则报错。
5.如果子父类中,出现了重名的成员,会优先使用子类的,此时如果一定要在子类中使用父类的怎么办?
①可以通过super关键字,指定访问父类的成员。
格式:super.父类成员变量/父类成员方法
②可以通过this关键字,指定访问子类的成员。
格式:this.子类成员变量/子类成员方法
6.继承后:方法重写
在继承体系中,子类出现了和父类中一摸一样的方法声明,我们就称子类这个方法是重写的方法。
7.方法重写的应用场景
①当子类需要父类的功能,但父类的该功能不完全满足自己的需求时。
②子类可以重写父类中的方法。
8.@Override重写注解:
放在重写后的方法上,作为重写是否正确的校验注解。
作用:
1.这个方法必须是正确重写的;
2.提高代码的可读性,代码优雅。
注意:
①重写方法的名词称、形参列表必须与被重写方法的名称和参数列表一致。
②私有方法不能被重写。
③子类重写父类方法时,访问权限必须大于或者等于父类。
④子类不能重写父类的静态方法,如果重写会报错。
9.方法重写案例:
旧手机的功能只能是基本的打电话,发信息;
新手机的功能需要能够在基本的打电话下支持视频通话。基本的发信息下支持发送语音和图片。
public class extends_Test1 {
public static void main(String[] args) {
//方法重写
newphone nw = new newphone();
nw.call();
nw.sending();
}
}
/*
新手机:子类
*/
class newphone extends phone{
//重写的方法
@Override//1.这个方法必须是正确重写的;2.提高代码的可读性,代码优雅。
public void call(){
super.call();//先用父类的基本功能
System.out.println("开始视频通话");
}
//重写的方法
@Override
public void sending(){
super.sending();//先用父类的基本功能
System.out.println("发送有趣的图片~~");
}
}
/*
旧手机:父类
*/
class phone{
public void call(){
System.out.println("打电话");
}
public void sending(){
System.out.println("发短信");
}
}
10.继承后:子类继承父类后构造器的特点:
子类所有构造器都会先访问父类构造器,再调用自己的构造器,初始化父类的数据。
为什么?
①子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。
②子类初始化之前,一定要调用父类构造器先完成父类数据空间的初始化。
怎么调用父类构造器?
子类构造器的第一行语句默认都是:super(),不写也存在。
11.继承后:子类构造器访问父类有参构造器?
①super调用父类有参构造器的作用:
初始化继承自父类的数据;
②如果父类中没有无参数构造器,只有有参构造器,会出现什么现象呢?
会报错,因为子类默认是调用父类无参构造器的。
③如何解决?
子类构造器中可以书写super(...),手动调用父类的有参数构造器。
12.代码演示:
子类:猫类
public class cat extends dog {
public cat(){
System.out.println("子类cat无参数构造器被执行~~");
}
public cat(String name){
System.out.println("子类cat有参数构造器被执行~~");
}
}
父类:狗类
public class dog {
public dog(){
System.out.println("父类dog无参数构造器被执行~~");
}
}
实现类:main
public class test1 {
public static void main(String[] args) {
//继承后子类构造器的特点
cat c1 = new cat();
System.out.println(c1);
System.out.println("----------");
cat c2 = new cat("金毛");
System.out.println(c2);
}
}
13.this和super小结
this:代表本类对象的引用;super:代表父类存储空间的标识
this()和super()必须要在第一行,所以一个构造器中不能共存this()和super();
this :访问子类当前对象的成员
super :在子类方法中指定访问父类的成员
this(...) :访问本类兄弟构造器
super(...) : 在本类构造器中指定访问父类的构造器
14.代码演示:
动物类(父类):
public abstract class Animal {
public String name = "动物名";
public void eat() {
System.out.println("动物要吃东西!");
}
public static String location = "长隆动物园";
public abstract void run();
}
老虎类(子类):
public class Tiger extends Animal {
public static boolean location;
String name = "老虎名";
public void showName(){
String name = "局部名";
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
super.eat();
this.eat();
}
@Override // 1、重写校验注解,加上之后,这个方法必须是正确重写的,这样更安全 2、提高代码的可读性
/**1、重写的名字和形参列表必须与被重写的方法一样
* 2、私有方法不能被重写
* 3、子类重写父类方法时,访问权限必须大于或者等于父类( 访问权限:privase < 不写 < protected < public)
* 4、静态方法不能被子类重写
*/
public void eat(){
super.eat();//方法重写,重写父类
System.out.println("老虎在吃东西");
}
@Override
public void run() {
}
}
实现类:
//extends :子类继承父类 让一个类与另一个类建立父子关系,用于提高代码复用性(子类extends 父类)
//父类(super)、子类(this)
public class extends_Demo4 {
/** 继承的特点:
* 1、子类有自己的构造器,不能继承父类的构造器
* 2、子类是否可以继承父类的私有成员(可以继承父类的私有成员,只是不能直接访问! )
* 3、子类是否可以继承父类的静态成员(不是继承,是共享的父类的)
* 4、java只能继承一个父类,不支持多继承,不过支持多层继承。 多层继承: A继承B,B继承C;
* 5、object :object是祖宗类
* 在子类中给访问成员(成员变量、成员方法)满足:就近原则(局域对象<子类对象<父类对象)
*/
//子类所有构造器都会先访问父类构造器,再调用自己的构造器,初始化父类的数据
/**
* this()和super()必须要在第一行,所以一个构造器中不能共存this()和super();
* this :访问子类当前对象的成员
* super :在子类方法中指定访问父类的成员
* this(...) :访问本类兄弟构造器
* super(...) : 在本类构造器中指定访问父类的构造器
*/
public static void main(String[] args) {
Tiger t = new Tiger();
t.eat();
System.out.println(Tiger.location);
t.showName();
}
}