static abstract final
static
static 目的:管理内存
static关键字属于类,而不是类的实例
静态(static)
可以是:
1.类 => 属于类,不属于任何方法
2.方法
3.代码块
静态属性:
cnt
属于Master
类的属性
所有类的对象共享一份空间
public class Master {
static int cnt = 0;//静态属性
//只存一份,属于类
}
//**另一个包**//
public class Demo {
public static void main(String[] args){
Master m0 = new Master();
m0.cnt ++;
System.out.println(m0.cnt);
Master m1 = new Master();
m1.cnt ++;
System.out.println(m1.cnt);
}
}
/*输出
1
2
*/
//-------------------------------------------------------------------------------
public class Master {
static int cnt = 0;//静态属性
}
//**另一个包**//
public class Demo {
public static void main(String[] args){
//cnt 为静态属性,只有一份,属于‘Master’这个类
System.out.println(Master.cnt);
Master.cnt ++;
System.out.println(Master.cnt);
Master.cnt ++;
System.out.println(Master.cnt);
}
}
/*输出
0
1
2
*/
静态方法:
语法:类名.静态方法名
public class Master {
public static void m1(){
System.out.println("这是m1的静态方法");
m2();
//m3();
//1.静态方法 只能调用 静态方法
//与类的加载有关
//因为加载时,优先加载静态的对象,此时非静态类的东西还没有加载,所以不能调用
//2.在静态里 不能用 this super
//因为this super 在new一个对象之后才可以使用
new Master().m3();
}
public static void m2(){
System.out.println("这是m2的静态方法");
}
public void m3(){
System.out.println("这是m3的普通的方法");
}
}
public class Demo {
public static void main(String[] args){
Master.m1();
}
}
/*
这是m1的静态方法
这是m2的静态方法
这是m3的普通的方法
*/
可以继承,不能重写,没有多态
public class Master {
public static void m1(){
System.out.println("这是m1的静态方法");
m2();
new Master().m3();
}
public static void m2(){
System.out.println("这是m2的静态方法");
}
public void m3(){
System.out.println("这是m3的普通的方法");
}
}
public class Pet extends Master{
//构不成重写
public static void m1(){
System.out.println("这是子类的方法");
}
}
public class Demo {
public static void main(String[] args){
Master m = new Pet();
m.m1();
//如果构成多态的话应输出:Pet.m1();
Pet m2 = new Pet();
m2.m1();//隐藏了父类的静态方法,不叫重写
}
}
/*输出
这是m1的静态方法
这是m2的静态方法
这是m3的普通的方法
这是子类的方法
*/
静态代码块
作用:初始化
时机:类加载时,只执行一次静态代码块
先初始化静态属性,再执行静态代码块
public class Master {
static int money = 888;
static{
System.out.println(money);
System.out.println("这里是静态代码块,可以做一些初始化");
}
}
public class Demo {
public static void main(String[] args){
new Master();
new Master();
}
}
/*
888
这里是静态代码块,可以做一些初始化
*/
可以看到我们new Master()
执行了两次,却只输出了一次结果
所以只执行一次静态代码块
总结:
1.static修饰的成员为静态成员,无需创建对象,可直接通过类名访问
2.静态方法不能直接访问非静态成员
3.静态方法中不能使用this
或 super
4.静态方法可以继承,不能重写,没有多态
5.静态代码块在类加载时被执行,且只执行一次
abstract
抽象类
概念:
被abstract修饰的类,成为抽象类。
抽象类 ==> 不够完整的类,不够具体的类
抽象(abstract)
例如:对于“动物”,是抽象的概念,不是具体的事物
假设有public class Animal {}
“动物类”
从语法的角度是可以创建的
但是从实际意义出发,这样的创建是没有意义的,因为它不是具体的“猫🐱”,或者“狗🐕”
【现实世界中只存在“动物”的子类,而不存在“动物”这个对象】
作用:
1.abstract 修饰类,被修饰的类不能new()对象
abstract class Pet{
String name,sex;
}
//----------------------------------------------------------------------------//
public class Demo {
public static void main(String[] args){
//Pet pet = new Pet();报错 --> 无法实例化
//Pet 是抽象的 不能具体化
}
}
2.可被子类继承,提供 共性属性和方法
abstract class Pet{
String name,sex;
}
//-----------------------------------------------------------------------------//
public class Cat extends Pet {
public void Live(){
System.out.println("coke小猫正在直播吃鱼ing <。)#)))≦ ");
}
}
//-----------------------------------------------------------------------------//
public class Dog extends Pet {
public void Action(){
System.out.println("骨架狗 U•ェ•*U 正在演戏");
}
}
//-----------------------------------------------------------------------------//
public class Demo {
public static void main(String[] args){
//Pet pet = new Pet();报错 --> 无法实例化
Pet p1 = new Cat();
Pet p2 = new Dog();
p1.name = "Coke";
p2.name = "骨架狗";
System.out.println(p1.name);
System.out.println(p2.name);
}
}
/*输出
Coke
骨架狗
*/
Cat(),Dog()继承了Pet()类的属性
Pet()不能被创建,只能为子类提供属性和方法
3.可声明为引用,更自然的使用多态
抽象方法:被abstract修饰的方法,称为抽象方法
对于类,必须包含在抽象类中
可以出现在 抽象类 , 接口 中
abstract class Pet{
public abstract void show();
}
public class Cat extends Pet {
@Override
public void show(){//实现重写
System.out.println("coke小猫正在直播吃鱼ing <。)#)))≦ ");
}
}
public class Dog extends Pet {
@Override
public void show(){//实现重写
System.out.println("骨架狗 U•ェ•*U 正在演戏");
}
}
public class Demo {
public static void main(String[] args){
Pet dog = new Dog();
Pet cat = new Cat();
//调用的父类方法,实际上执行子类的方法
dog.show();
cat.show();
}
}
/*输出
骨架狗 U•ェ•*U 正在演戏
coke小猫正在直播吃鱼ing <。)#)))≦
*/
总结:
abstract修饰类:抽象类对象无法独立存在,即不能 new 抽象类()
,但可以声明引用
abstract修饰方法:只有方法声明,没有方法实现(需要包含在抽象类中)
子类继承抽象类后,必须重写父类中所有的抽象方法,否则子类还是抽象类
抽象类中不一定有抽象方法,但有抽象方法的类一定是抽象类
final
概念:最后的,不可更改的
final可修饰的内容:
1.类(最终类)
2.方法(最终方法)
3.变量(也就是 常量)
1.final修饰类:此类不能被继承
//Demo类被final修饰不能被继承
public final class Demo {
public static void main(String[] args){
}
}
2.final修饰方法:此方法不能被重写 ,但仍可以继承
public class Master {
public final void show(){
System.out.println("主人正在展示他的宠物");
}
}
public class Pet extends Master{
//父类的show()方法已经被final修饰,不能对其重写
//public void show(){
//System.out.println("宠物正在展示自己");
//}
}
public class Demo {
public static void main(String[] args){
Pet p = new Pet();
p.show();
}
}
/*输出
主人正在展示他的宠物
*/
final修饰变量
必须赋初值
类似C语言中的const
被修饰的变量就是一个常量,例如π
普通常量
赋值时机:
1.初始化
public class Master {
final int N = (int) (2e5 + 9);
}
2.动态代码块
public class Master {
final int N;
{
N = (int)2e5 + 9;
}
}
3.构造方法
public class Master {
final int N;
Master(){
N = (int)2e5 + 9;
}
}
静态常量
赋值时机:
1.初始化
public class Master {
static final int N = (int)2e5 + 9;
}
2.静态代码块
public class Master {
static final int N;
static {
N = (int)2e5 + 9;
}
}
对象常量 final修饰引用(只能指向一个对象)
public class Master {
int n;
}
public class Demo {
public static void main(String[] args){
final Master m = new Master();
m.n = 721;
System.out.println(m.n);
//m = new Master();
}
}
/*输出
721
*/
1.该引用只能指向1个对象 并且它只能永远指向该对象无法再指向其他对象
2.在该方法执行过程中,该应用指向该对象之后,该对象不会被垃圾回收器回收,直到当前方法结束,
才会释放空间
3.虽然final的引用指向对象A后,不能重新指向对象B但是对象A内部的数据可以被修改
也就是可以修改引用指向的堆里面的数据,而不可以修改引用
【引用类似C语言里面的指针变量,里面存的是一个地址】
总结:
final修饰类:此类不能被继承
final修饰方法;此方法不能别重写
final修饰变量:此变量值不能被改变(无初始值,只允许赋值一次)
局部常量:显式初始化
实例常量;显式初始化,动态代码块,构造方法
静态常量:显式初始化,静态代码块
基本类型常量:值不可变
引用类型变量:地址不可变