1、static关键字
static,用于描述被所有对象共享的成员,不是对象独享
如果属性没有加static修饰,称为对象属性或实例变量
如果方法没有加static修饰,称为对象方法或实例方法
如果属性有static修饰, 称为静态属性, 或 类属性, 或 类变量
如果方法有static修饰, 称为静态方法, 或 类方法
什么对象的属性应该是static?
这个属性是被所有对象共享的数据
什么方法应该是static?
这个方法不需要调用者对象,因为不依赖对象数据
(方法本身是静态,但是调用时就是非静态的)
静态和非静态如何区分?
静态:存在是确定的,类的存在是确定的唯一的,所以是静态的
非静态:存在是不确定的,对象的存在取决于new操作,不是唯一的,所以是非静态的, 构造器是非静态的
被static修饰的成员有何特点?
1)随着类的加载而加载
2)优先于对象存在
3)修饰的成员,被所有对象所共享
4)访问权限允许时,可不创建对象,直接被类调用
静态成员可以直接互访???
静态成员指静态属性和静态方法,可以互访
静态环境中可以直接访问非静态成员吗?
非静态环境中可以直接访问静态成员
静态环境中不可以直接访问非静态成员,原因是静态方法的调用没有对象,也就没有this, 当然也没有super
在静态方法中可以创建一个对象, 再通过对象间接访问对象成员是可以的,但是最终落实方法调用的不是对象, 仍然是类.
什么是静态语句块?
静态语句块, 也称为静态初始化器, 它是隶属于类, 在类加载时执行仅有一次, 作用是对类进行初始化.
编译器会把所有静态块和静态属性的显式赋值整合成一个静态方法叫 <clinit>
什么是非静态语句块?
非静态语句块, 隶属于对象, 会在创建对象时执行仅有一次, 作用是对对象进行初始化
编译器会把所有非静态块和属性的显式赋值整合一下, 再把构造器整合在后面形成一个方法 <init>
非静态块总是先于构造器执行, 并且无论调用哪个构造器, 非静态块总是要执行.
补充说明:
子类继承父类时, 继承父类的所有成员(属性和方法和内部类)
继承本质 : 子类是父类, 拥有父类的所有成员.
成员 : 具有描述性的东西. 构造器和语句块不是成员.
只有非静态方法才具有多态性.
2、单例设计模式
什么是单例?
单例:一个类只允许一个对象存在
饿汉式单例和懒汉式单例
饿汉式单例:累加载时就创建对象 1)封死new 2)声明私有静态引用,指向唯一对象 3)声明公用静态方法,用于获取对象地址
优点:线程安全 使用于创建对象简单快速
懒汉式单例:别人要获取对象时创建 1)封死new 2)声明私有静态引用,指向唯一对象 3)声明公用静态方法,用于获取对象地址
缺点:存在线程安全问题 适用于创建对象复杂时间长的情况,延迟创建对象
代码实现
//饿汉式单例:声明引用的同时创建对象
class Singleton1{
//是能在类中创建唯一对象,并使用属性去引用这个对象
private static Singleton1 only = new Singleton1();//必须加static 他才能在方法区 才能在main方法中使用 且必须私有化,防止外部数据修改的导致其断开和唯一对象的引用
//提供公共静态方法,用于获取对象的地址
public static Singleton1 getInstance(){
return only;
}
//私有化构造器,外部不可以随意使用new
private Singleton1(){}
}
//懒汉式单例:不会在对象声明的时候创建,而是被调用时才创建对象
class Singleton2{
private static Singleton2 only = null;
//通过公共方法来访问类的实例
public static Singleton2 getInstance(){
if(only == null){//第一次创建时才创建,确保对象的唯一性
only = new Singleton2();
}
return only;
}
//封死构造器
private Singleton2() {
}
}
//单例测试类
public class singletonTest {
public static void main(String[] args) {//Runtime举例测试 饿汉式单例
Runtime rt1 = Runtime.getRuntime();
Runtime rt2 = Runtime.getRuntime();
System.out.println(rt1 == rt2);//true
}
public static void main2(String[] args) {
Singleton2 s1 = Singleton2.getInstance();
Singleton2 s2 = Singleton2.getInstance();
System.out.println(s1 == s2);//false 不单例 因为每调用一次就new一次 所以需要加一个判断 判断是否是第一次创建 判断完后 执行结果为true
}//测试懒汉式单例
public static void main1(String[] args) {
// Singleton1 s1 = new Singleton1();
// Singleton1 s2 = new Singleton1();//单例是无论有多少个引用,引用的地址都是指向同一个对象
// System.out.println(s1 == s2);//不是单例 false
// Singleton1 s1 = Singleton1.only;//通过访问属性拿到对象
// Singleton1.only = null; //如果给它一个空,那么所指的那个对象就会断开,那么唯一的对象就被删除了 所以这个对象在创建时应就封装起来
// Singleton1 s2 = Singleton1.only;
// System.out.println(s1 == s2);//true
Singleton1 s1 = Singleton1.getInstance();//因为only属性所指的对象被封装起来了,所以这里只能访问 不能修改
Singleton1 s2 = Singleton1.getInstance();
System.out.println(s1 == s2); //true
}//测试饿汉式单例
}
3、链表
删除分析
代码实现
package com.atguigu.javase.test;
class Node{//结点类
int value;//值域
Node next;//指针域
}
class Link{
private Node head = null;
private Node tail = null;
public void add(int val){//通过方法来添加数据
Node newNode = new Node();
newNode.value = val;//携带数据
if(head == null ){//第一次插入
head = newNode;//头结点的引用
tail = newNode;//尾结点的引用
}else{//链表非空 尾部插入
tail.next = newNode;//修改尾节点指向节点的的next的地址
tail = newNode;//修改尾节点的地址
}
}
public void travel(){//遍历链表
Node tmp = head;
while(tmp != null){
System.out.println(tmp.value);
tmp = tmp.next;
}
}
public boolean remove(int val){//删除一个节点
Node prev = head; //从头结点开始去查找
while(prev.next != null){
if(prev.next.value == val){//定位成功
//删除的目标结点是prev.next
prev.next = prev.next.next;
return true;
}
prev = prev.next;
}
return false;
}
public int size(){//返回元素个数
return 0;
}
}
public class FunnyTest {
public static void main(String[] args) {
Link link = new Link(); //创建一个Link对象
link.add(10);
link.add(20);
link.add(50);
link.add(70);
link.add(80);
link.travel();
link.remove(80);
}
}
4、final关键字
1)final是终极的, 最终的, 是形容词, 可以修饰类, 方法, 变量.
2)final修饰类 表明这个类是最终类, 这个类不可以被继承(被扩展)
3)final修饰方法,表明这个方法是终极方法. 不允许被子类重写.
4)final修饰变量, 表明这个量是最终量, 它必须要求只能赋值一次.
/* 子类中不允许重写final方法. @Override public void finalTest() { }*/
public static final 修饰的是全局常量
空final ,在构造器中进行初始化
5、抽象类
具体类:对现实世界某种事物的描述(cat)
抽象类:对现实世界某类不同种的描述(pet),抽象类中可以包含抽象方法, 也可以包含其他成员.
抽象方法:只有方法声明,没有方法体,不可执行,一定要被继承,子类一定要重写
public abstract void speak(); // 抽象方法
抽象方法表明这类事物应该具有的某种行为, 但是又因为类型太模糊, 无法确定其行为方式, 所以完全不写方法体
具体类不可以包含抽象方法.
抽象类不可以创建对象, 因为它有可能包含有抽象方法, 万一创建成功,就调用抽象方法. 就出问题
总结
今天学习的内容:
1)static关键字;
2)单例设计模式;
3)链表;
4)final关键字;
5)抽象类型