static
类变量
适用范围
在java类中,可以用static修饰属性、方法、代码块、内部类
被修饰后的成员具备以下特点
随着类的加载而加载
优先于对象存在
修饰的成员被所有对象所共享
访问权限允许时可不创建对象,直接被类调用
类方法
做工具类用的多
static方法内部不能有this和super
重载的方法需要同时为static或者非static
单例设计模式
设计模式
在实际编程过程中逐渐总结出的一些解决问题的套路
单例
只有一个实例(实例化对象)
在整个软件系统运行过程中,这个类只被实例化一次,之后不论在哪都只调用这一个实例
单例设计模式–饿汉式
做一个私有的构造
饿汉式的实现
public class Single {
//私有的构造,构造方法私有化,调用这个类的人就不能直接使用new来创建对象
private Single(){
}
//私有的Single类型的类变量
private static Single single = new Single();
public static Single getInstance(){
return single;
}
}
单例设计模式–懒汉式
最开始的对象是null,直到第一次被调用时再new一个对象
懒汉式实现
public class Single1 {
//私有构造方法
private Single(){
}
private static Single1 s1 = null ;
public static Single1 getInstance(){
if(s1 == null)
s1 = new Single1();
return s1;
}
}
初始化块
非静态代码块
可以有输出语句
可以对类的属性声明进行初始化操作
可以调用静态和非静态的变量或方法
若有多个非静态的代码块,那么按照从上到下的顺序依次执行
每次创建对象的时候都会执行一次,且优先于构造器执行
public class Person1 {
String name;
public Person1(){
this.name = name ;
System.out.println("执行的是构造方法");
}
//非静态的代码块
{
System.out.println("执行的是非静态代码块");
}
{
System.out.println("代码块2");
}
}
public class person1test {
public static void main(String[] args) {
new Person1();
}
}
执行代码之后的结果
执行的是非静态代码块
代码块2
执行的是构造方法
在new Person1();执行的时候
1、类的属性的默认初始化和显示初始化
2、执行代码块的代码,多个代码块按顺序执行
3、执行构造器的代码
静态代码块
静态代码块只能使用静态static修饰的属性和方法,不可以调用非静态的属性和方法
静态代码块只能被执行一次
可以有输出语句
可以对类的属性声明进行初始化操作
若有多喝静态代码块,那么按照从上到下的顺序依次执行
静态代码块的执行要优先于非静态代码块
在实际开发中,static静态代码块用在初始化类的静态属性(static类型属性)
执行顺序,转:https://blog.csdn.net/sinat_33921105/article/details/79509638
静态代码块会随着类的加载而执行,而且只执行一次。当new StaticTest()开始执行的时候会先去执行父类中的静态代码块,然后再执行子类中的静态代码块,当所有的静态代码块都执行结束后会执行main函数中的输出语句(前提是输出语句在new StaticTest()之前),然后会去执行父类中的非静态代码块,接着是父类中的构造方法,紧接着执行子类中的非静态代码块,最后是子类中的构造方法
匿名内部类
public class Person1 {
String name;
public Person1(){
this.name ="zhangsan";
System.out.println("执行的是构造方法");
}
//非静态的代码块
{
System.out.println("执行的是非静态代码块");
}
{
System.out.println("代码块2");
}
public void test1(){
System.out.println("Person1的test方法");
}
}
public class person1test {
public static void main(String[] args) {
//new Person1();
//匿名内部类
Person1 p = new Person1(){
@Override
public void test1() {
System.out.println("========");
}
};
System.out.println(p.name);
}
}
构建了一个没有类名的Person1子类,也就是匿名的Person1子类
这种类没有类名,不能用显式地new方法创建对象(没有构造器),这样的情况就要用代码块{}进行初始化操作
如果想在匿名内部类中将name改成lisi(不改动Person1的代码),用代码块代替构造方法。
public class person1test {
public static void main(String[] args) {
//new Person1();
//匿名内部类
Person1 p = new Person1(){
{ //用代码块代替构造方法
super.name = "lisi";
}
@Override
public void test1() {
System.out.println("========");
}
};
System.out.println(p.name);
}
}
final关键字
在Java中声明类、属性和方法时可以使用final关键字来修饰。
final标记的类不能被继承。提高安全性,提高程序的可读性
String类、System类、StringBuffer类
final标记的方法不能被子类重写
Object类中的getClass()
final标记的变量(成员变量或局部变量)即称为常量。名称大写,且只能被赋值一次
final标记的成员变量必须在声明的同时或在每个构造方法中或代码块中显示赋值,然后才能使用
抽象类
用关键字abstract来修饰一个类时,这个类叫做抽象类
用abstract修饰一个方法时,这个方法叫做抽象方法
抽象方法:只有方法声明,没有方法的实现,以分好结束:
abstract int abstractMethod(int a);
含有抽象方法的类必须被声明为抽象类
抽象类不能被实例化,抽象类是用来被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类
不能用abstract修饰属性、私有方法、构造器、静态方法、final方法。
public abstract class Animal {
public abstract void test();
public abstract void move();
}
class dog extends Animal {
@Override
public void move() {
}
@Override
public void test() {
}
}
//bird类
abstract class bird extends Animal{
@Override
public void test() {
}
public abstract void move();
}
为什么抽象类不能使用final关键字声明
final修饰的类是最终的类,不能被继承
抽象类必须被继承才能被使用
抽象类中可以定义构造器吗
抽象类可以由构造方法,只是不能直接创建抽象类的实例对象
抽象类不能实例化
例题
编写一个 Employee类,声明为抽象类,包含如下三个属性:name,id,salary。提供必要的构造器和抽象方法:work()。对于 Manager类来说他既是员工,还具有奖金( bonus)的属性。请使用继承的思想,设计Commonemployee类和 Manager类,要求类中提供必要的方法进行属性访问。
(此外还另外加了一个继承Manager类的子类puple类)
abstract public class Employee1 {
String name;
int id;
double salary;
public abstract void work();
public Employee1(){
}
}
class Manager1 extends Employee1{
double bonus;
@Override
public void work() {
System.out.println("this is a Manager");
}
public void setManegerInfo(int id,String name,double salary,double bonus){
super.id=id;
super.name=name;
super.salary=salary;
this.bonus = bonus;
}
public void getCommonEmployee(){
System.out.println("name = "+super.name +" id = "+ super.id +" salary = "+ super.salary + " bonus = "+ bonus);
}
}
class CommonEmployee extends Employee1{
@Override
public void work() {
System.out.println("this is a CommonEmployee");
}
public void setCommonEmployeeInfo(int id,String name,double salary){
super.id=id;
super.name=name;
super.salary=salary;
}
public void getCommonEmployee(){
System.out.println("name = "+super.name +" id = "+ super.id +" salary = "+ super.salary);
}
}
class puple extends Manager1{
int studentId;
public void work(){
System.out.println("this is a puple!");
}
public void setManegerInfo(int id,String name,double salary,double bonus,int studentId){
super.id=id;
super.name=name;
super.salary=salary;
super.bonus = bonus;
this.studentId = studentId;
}
public void getPuple(){
System.out.println("name = "+super.name +" id = "+ super.id +" salary = "+ super.salary + "bonus = "+ bonus + "studentId = "+studentId );
}
}
public class Employee1Test {
public static void main(String[] args) {
// puple pu = new puple();
// pu.setManegerInfo(999,"puplegod",99.99,99.1,893);
// pu.getPuple();
CommonEmployee ce = new CommonEmployee();
ce.work();
ce.setCommonEmployeeInfo(188,"lisi",99.9);
ce.getCommonEmployee();
Manager1 ma = new Manager1();
ma.work();
ma.setManegerInfo(991,"god",11.1,11.445);
ma.getCommonEmployee();
}
}
//输出结果
this is a CommonEmployee
name = lisi id = 188 salary = 99.9
this is a Manager
name = god id = 991 salary = 11.1 bonus = 11.445