1、static关键字的基本概念
- 使用static关键字修饰成员变量表示静态的含义,此时成员变量由对象层级提升为类层级,也就是整个类只有一份并被所有对象共享,该成员变量随着类的加载准备就绪,与是否创建对象无关。
- static关键字修饰的成员可以使用引用.的方式访问,但推荐类名.的方式
private String country; //隶属于对象层级,也就是每个对象都拥有独立的一份
private static String country; //隶属于类层级,也就是整个类只有一份并且被所有对象共享
People.country; //类名.的方式 //null
2、static关键字的使用
- 在非静态成员方法中既能访问非静态的成员又能访问静态的成员(成员:成员变量+成员方法,静态成员被所有对象共享)
- 在静态成员方法中只能访问静态成员不能访问非静态成员(成员:成员变量+成员方法,因为此时可能还没有创建对象)
- 在以后开发中只能隶属于类层级并被所有对象共享的内容才可以使用static关键字修饰。(不能滥用static关键字)
private int cnt=1;//隶属于对象层级
private static int snt=2;//隶属于类层级
//自定义非静态成员方法 需要使用引用.的方式访问
public void show(){
sout(this.cnt);//1
sout(this.snt);//2
}
//自定义静态成员方法 推荐使用类名.的方式访问
public static void show2(){
//sout(this.snt) // error
//sout(cnt); //静态方法中没有this关键字,因为是可以通过类名.方式调用,ST.show2()报错了,此时并没有创建cnt对象
sout(snt);
}
main(String[] args){
ST st=new ST();
st.show();
ST.show2(); //error
}
private static String country;
public static String getCountry(){
return country;
}
//静态方法中不能使用this,所以采用类名.的方式访问
public static void setCountry(String country){
People.country = country;
}
3、构造块和静态代码块(熟悉)
- 构造块:在类中直接使用{}括起来的代码块
- 每创建一个对象都会执行一次构造块
- 静态代码块:使用static关键字修饰的构造块
/*
编程实现构造块和静态代码块的使用
*/
public class BlockTest{
//当需要在执行构造方法体之前做一些准备工作时,则将准备工作的相关代码写在构造块中即可,比如:对成员变量进行的统一初始化操作
{
sout("构造块");
}
//自定义构造方法
BlockTest()[
sout("构造方法体");
}
main(String[] args){
BlockTest bt = new BlockTest();
BlockTest bt2 = new BlockTest();
// 结果:
// 构造块 构造方法体
// 构造块 构造方法体
}
}
/*
编程实现构造块和静态代码块的使用
*/
public class BlockTest{
//当需要在执行构造方法体之前做一些准备工作时,则将准备工作的相关代码写在构造块中即可,比如:对成员变量进行的统一初始化操作
{
sout("构造块"); //第二步执行
}
//静态代码块会随着类的加载而准备就绪,会先于构造块执行
//当需要在执行代码块之前随着类的加载做一些准备工作时,则编写代码到静态代码块中,比如:加载数据库的驱动包等
static {
sout("静态代码块"); //第一步执行
}
//自定义构造方法
BlockTest()[
sout("构造方法体"); //最后一步执行
}
main(String[] args){
BlockTest bt = new BlockTest();
BlockTest bt2 = new BlockTest();
//结果:
//静态代码块 (只执行了一次)
//构造块 构造方法体
//构造块 构造方法体
}
}
4、main方法的详解
- 语法格式:public static void main(String[] args){} main方法是特殊的静态类,JVM在调用
- 参数使用举例
/*
编程实现main方法的测试
*/
public class MainTest{
public static void main(String[] args){
for(int i=0;i<args.length;i++)
{
sout("下标为"+i+"形参变量为"+args[i]);
}
}
}
//使用JVM来执行调用
//在CMD命令行中输入
javac MainTest.java
java MainTest 张飞 关羽 刘备 //回车
//打印结果
//下标为0形参变量为张飞
//下标为1形参变量为关羽
//下标为2形参变量为刘备
/**
* @author XiceSberg
* @date 2020/7/25 7:26
* @description:编程实现Singleton的封装
*/
public class Singleton {
//2.声明本类类型的引用指向本类类型的对象,使用 private static 关键字共同修饰
private static Singleton sin = new Singleton();
//1.私有化构造方法,使用private关键字修饰
private Singleton(){}
//3.提供公有的get方法负责将对象返回出去
public static Singleton getInstance() {
return sin;
}
}
/**
* @author XiceSberg
* @date 2020/7/25 7:30
* @description:编程实现SingletonTest对Singleton类进行测试,
* 要求main方法能得到且只能得到该类的一个对象
*/
public class SingletonTest {
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1 == s2); //true
}
}
5、单例设计模式
- 私有化构造方法,使用private 关键字修饰
- 声明本类类型的引用指向本类类型的对象,使用 private static 关键字共同修饰
- 提供公有的get方法负责将对象返回出去,并用public static关键字共同修饰
/**
* @author XiceSberg
* @date 2020/7/25 7:26
* @description:编程实现Singleton的封装
*/
public class Singleton {
//2.声明本类类型的引用指向本类类型的对象,使用 private static 关键字共同修饰
//private static Singleton sin = new Singleton(); //饿汉式
private static Singleton sin = null; //懒汉式
//1.私有化构造方法,使用private关键字修饰
private Singleton(){}
//3.提供公有的get方法负责将对象返回出去
public static Singleton getInstance() {
// return sin; //饿汉式
if(null == sin){
sin = new Singleton(); //懒汉式 多线程共享资源,开发中推荐使用懒汉式
}
return sin;
}
}
6、继承的概念
- 在JAVA语言中使用extends(扩展)关键字来表示继承关系。
=》如:public class Worker extends Person{} -表示Worker类继承自Person类
=》其中:Person类叫做超类,父类,基类
=》其中:Worker类叫做派生类,子类,孩子类
- 使用继承提高了代码的复用性,可维护性及扩展性,是多态的前提条件。
7、继承的特点
- 子类不能继承父类的构造方法和私有方法,但私有成员变量可以被继承 只是不能直接访问。
- 无论使用何种方式构造子类的对象时都会自动调用父类的无参构造方法, 来初始化从父类中继承的成员变量,相当于在构造方法的第一行增加代 码super()的效果
- 使用继承必须满足逻辑关系:子类 is a 父类,也就是不能滥用继承。
- Java语言中只支持单继承不支持多继承,也就是说一个子类只能有一个父 类,但一个父类可以有多个子类。
public Worker() {
super();//表明调用父类的无参构造方法,若没有加则编译器自动添加
}
public Worker(String name, int age, int salary) {
super(name,age); //调用父类的有参构造方法
setSalary(salary);
}
Worker w2=new Worker("张飞",22,500);
w2.show(); //张飞,22
8、方法重写的概念
- 从父类中继承下来的方法不满足子类的需求时,就需要在子类中重新写 一个和父类一样的方法来覆盖从父类中继承下来的版本,该方式就叫做 方法的重写(Override)。
//自定义show方法覆盖从父类中继承的版本
@Override //标注,注解,用于说明下面的方法是对父类方法的重写,若没有构成重写则编译报错
public void show() {
super.show();//表示调用父类的show方法
}
9、方法重写的原则
- 要求方法名相同、参数列表相同以及返回值类型相同,从Java5开始允许 返回子类类型。
- 要求方法的访问权限不能变小,可以相同或者变大。
- 要求方法不能抛出更大的异常(异常机制)。
//父类返回类型为Person
public Person show(){}
//子类返回类型也需要是Person
public Person show(){}
//JAVA5开始,子类返回类型可以是子类类型Worker
public Worker show(){}
10、又见构造块与静态代码块(笔试)
- 先执行父类的静态代码块,再执行子类的静态代码块。
- 执行父类的构造块,执行父类的构造方法体。
- 执行子类的构造块,执行子类的构造方法体
/**
* @author XiceSberg
* @date 2020/7/25 8:36
* @description
*/
public class SuperTest {
{
System.out.println("superTest类中的构造块"); //第三步执行
}
static {
System.out.println("superTest类中的静态代码块"); //第一步执行
}
public SuperTest() {
System.out.println("superTest类中的构造方法体"); //第四步执行
}
public static void main(String[] args) {
SuperTest st = new SuperTest();
}
}
/**
* @author XiceSberg
* @date 2020/7/25 8:39
* @description
*/
public class SubSuperTest extends SuperTest {
{
System.out.println("---SubSuperTest类中的构造块"); //第五步执行
}
static {
System.out.println("---SubSuperTest类中的静态代码块"); //第二步执行
}
public SubSuperTest() {
System.out.println("---SubSuperTest类中的构造方法体"); //第六步执行
}
public static void main(String[] args) {
SubSuperTest sst = new SubSuperTest();
/*
superTest类中的静态代码块
---SubSuperTest类中的静态代码块
superTest类中的构造块
superTest类中的构造方法体
---SubSuperTest类中的构造块
---SubSuperTest类中的构造方法体
*/
}
}
11、权限修饰符和包的定义
- public修饰的成员可以在任意位置使用。
- private修饰的成员只能在本类内部使用。
- 通常情况下,成员方法都使用public关键字修饰,成员变量都使用private 关键字修饰
12、package语句的由来
- 定义类时需要指定类的名称,但如果仅仅将类名作为类的唯一标识,则 不可避免的出现命名冲突的问题。这会给组件复用以及团队间的合作造 成很大的麻烦!
- 在Java语言中,用包(package)的概念来解决命名冲突的问题。
13、包的定义
- 在定义一个类时,除了定义类的名称一般还要指定一个包名,格式如下: package 包名; package 包名1.包名2.包名3...包名n;
- 为了实现项目管理、解决命名冲突以及权限控制的效果。
14、定义包的规范
- 如果各个公司或开发组织的程序员都随心所欲的命名包名的话,仍然不 能从根本上解决命名冲突的问题。因此,在指定包名的时候应该按照一 定的规范。
- org.apache.commons.lang.StringUtil
- 其中StringUtils是类名而org.apache.commons.lang是多层包名,其含义 如下:org.apache表示公司或组织的信息(是这个公司(或组织)域名的 反写);common 表示项目的名称信息;lang 表示模块的名称信息。
15、包的导入
- 使用import关键字导入包。
- 使用import关键字导入静态成员,从Java5.0开始支持。
//导入java目录中lang目录中System类中的静态成员out
import static java.lang.System.out;
out.println("可以这样来打印");//笔试可能出现,开发中基本不用
16、final修饰类和方法的作用 (重点)
- final本意为"最终的、不可改变的",可以修饰类、成员方法以及成员变量。
- final关键字修饰类体现在该类不能被继承。 - 主要用于防止滥用继承,如:java.lang.String类等。
- final关键字修饰成员方法体现在该方法不能被重写但可以被继承。 - 主要用于防止不经意间造成重写,
=》如:java.text.Dateformat类中format方法等。
- final关键字修饰成员变量体现在该变量必须初始化且不能改变。 - 主要用于防止不经意间造成改变,
=》如:java.lang.Thread类中MAX_PRIORITY等。
public final class FinalClass {
}
public class SubFinalClass extends FinalClass {//error FinalClass 被关键字final修饰了不能被继承
}
IDEA快捷键
ctrl+shift+/ 进行选中内容的多行注释,再来一次取消注释
ctrl+/ 进行当前行的单行注释,再来一次取消注释
sout 回车得到"System.out.println()"
main 回车得到"public static void main(String[] args){}"
去掉双击Shift会弹出一个框,(再次使用可以点击菜单栏Help中的Find Action)
选择Actions,输入registry...,双击进去后找ide.suppress.double.click.handler,
后面的Value打勾,就可以去掉这个弹框
public final void show(){
}
@Override
public void show() { //error show 方法不能被重写
super.show();
}
第一种:
private final int cnt = 1;//显示初始化
第二种:
private final int cnt;
{
cnt=2;//2 构造块进行初始化
}
第三种:error
private final int cnt = 1;//显示初始化
{
cnt=2;//2 构造块进行初始化 //error final修饰的变量不能赋值
}
第四种:
private final int cnt;
public FinalMemberTest
{
cnt=3;//3 构造方法体种进行初始化
}
17、final修饰成员变量的作用 (重点)
- 在以后的开发中很少单独使用final关键字来修饰成员变量,通常使用 public static final关键字共同修饰成员变量来表达常量的含义,常量的命 名规范要求是所有字母都要大写,不同的单词之间采用下划线连。
- public static final double PI = 3.14;