一、static关键字
1、static作用
static:修饰类中的成员变量和普通的方法。不能修饰构造方法。
被static修饰的变量或者方法可以通过类名直接访问,不需要去创建这个类的对象。
被static修饰的变量或者方法在使用的时候,不能直接访问非static修饰的内容。
2、static的演示
public class Circle {// 半径private double radius;/** 圆周率 : 是所有圆共享的一个常量数据,* 静态之后,变量就会在方法区的静态区中出现,* 而每次创建Circle对象的时候,对象在堆中的内存* 中就没有pi变量*/private static double pi = 3.14;public Circle( double radius ) {this.radius = radius;}public double getArea() {return pi * radius * radius;}
}
3、static的用法
- static修饰成员变量和普通的方法
- static修饰的方法不能调用非静态的方法(静态不能调用非静态)
- 非静态的成员变量和方法是可以直接访问静态的成员变量和方法。
4、main方法为什么是静态的
- main方法是程序的唯一入口,是被JVM直接调用
- JVM是通过JDK中的java命令启动。启动的时候是传递了当前的类名,然后JVM会直接到这个类中找固定格式的main方法(类名.main( new String[0] ))
二、public关键字
1、public作用
public是访问权限修饰,它可以修饰类、方法(普通和构造方法)或变量,被public修饰的类、方法或变量权限最大,在任何程序中都可以被访问。
2、public的使用
如果类被public修饰,要求这个类被保存的时候,文件名必须和当前的class的名称保持一致。
当类中的方法需要类意外的程序访问,直接使用public修饰,如果只是在本类中访问,直接使用private修饰。
3、为什么main修饰被public修饰
因为main是被JVM调用,如果权限不是最大的,那么JVM无法调用。
三、单例设计模式
3.1、单例设计模式介绍
在某些场景下会出现一个类必须要有对象,但是对象的必须是唯一的。这时就称这个类是单例的。
3.2、单例如何书写
/** 模拟单例类的书写*/
public class SingleClass {// 在这个类中创建本类的对象private static SingleClass instance = new SingleClass();// 可以将构造方法私有private SingleClass() { }// 将这个类的对象对外提供出去public static SingleClass getInstance() {return instance;}public void print() {System.out.println("Single .........");}
}
public class SingleTest {public static void main(String[] args) {// SingleClass 中没有书写构造方法,有个默认的构造方法// 可以通过空参数的构造方法创建出多个对象SingleClass sc = SingleClass.getInstance();SingleClass sc2 = SingleClass.getInstance();//SingleClass.instance = null;SingleClass sc3 = SingleClass.getInstance();System.out.println( sc );System.out.println( sc2 );System.out.println( sc3 );sc.print();sc.print();sc2.print();}
}
3.3、单例类的书写步骤
- 私有本类的构造方法
- 创建本类的对象(书写成员变量,指向本类的那个唯一的对象,成员变量私有)
- 对外提供静态的方法获取本类的对象
3.4、单例类常见2种书写方式
-
饿汉式
public class Single{// 创建本类对象private static Single instance = new Single();// 私有本类所有构造方法private Single(){}// 对外提供获取本类对象的方法public static Single getInstance(){return instance;} }
-
懒汉式
public class Single{// 只定义本类类型的一个引用变量private static Single instance = null;// 私有本类所有构造方法private Single(){}// 对外提供获取本类对象的方法public static Single getInstance(){// 这里需要对多线程访问进行控制(加锁|同步代码块)if( instance == null ){instance = new Single();}return instance;} }
开发中一般使用饿汉式,面试问懒汉式(静态、并发问题)。
四、继承
1、继承介绍
继承:类是描述某个事物群体的共性特点。生活中事物和事物之间一定存在着某些关系。
例如:
class Dog{ }
class Cat{ }
class Animal{ }
class Pig{ }
用Java中的类描述事物,事物之间有定的关系,说明类与类之间会存在关系。
在Java中类和类之间的关系称为:继承(extends)
2、继承演示
Java只支持单继承,不支持多继承,但支持多重继承。
class Fu{}
class Zi extends Fu{}
class Zi2 extends Fu{}
继承中名词:
子类:Zi属于子类
父类:Fu属于父类
class Person {private String name;private char sex;public String getName() {return name;}public void setName(String name) {this.name = name;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}
}class Student extends Person{private double score;private String sNo;public void eat() {System.out.println("eat");}public void study() {System.out.println("study");}
}
class Teacher extends Person {private double salary;private String tNo;public void eat() {System.out.println("eat");}public void work() {System.out.println("work");}
}public class ExtendsDemo {public static void main(String[] args) {Student s = new Student();s.setName("张三");}
}
子类继承父类,父类中的所有非私有的变量和方法(非构造方法)子类都可以继承到,创建子类对象是可以直接使用的。如果在子类的类中,不用创建对象也能直接访问。
3、继承细节问题
-
继承可以让子类直接使用父类中的行为等,但是不能因为可以使用父类中的行为而去继承某个类。
-
Java只支持单继承,不支持多继承,但支持多重继承。
class A{public void run(){} } class B{public void run(){} } // 多继承,java不支持 class C extends A , B{} class D extends A{} class E extends A{}class Test{public static void main(String[] args){C c = new C();// 这里的调用方法出现歧义,导致无法确定到底是用的A父类,还是B父类中的run方法c.run();} }
4、方法的复写(重写,覆盖)
/** 描述手机*/
class Phone {private String color;private double price;public void sendMessage() {System.out.println("发短信");}public void call() {System.out.println("打电话");}
}
class HuaWeiP40 extends Phone{/** 在子类中出现了和父类功能相同的方法,* 这时子类中可以直接复写(重写、覆盖 override )父类的这个方法* 然后在子类中去书写适合子类的方法体*/public void sendMessage() {System.out.println("发短信同时包含图片");}public void call2() {System.out.println("视频通话");}
}public class ExtendsDemo2 {public static void main(String[] args) {Phone p = new Phone();p.sendMessage();p.call();HuaWeiP40 hw = new HuaWeiP40();hw.sendMessage();}
}
方法的重写( 复写、覆盖 Override ):
-
在子父类之间,子类将父类的方法在子类的类体中重写了
-
方法复写要求:返回值类型、方法名、参数列表完全一致
-
复写时的方法的修饰符可以不一致,但是子类的方法的修饰符权限必须大于等于父类方法的权限,一般复写的时候,我们就沿用父类的权限即可。
-
创建子类对象,调用复写的方法,一定执行是子类复写的那个方法,而不会执行父类的方法。
如果子类没有复写父类的方法, 创建子类对象,调用方法的时候一定会执行父类中的方法
class Fu{int x = 12;public void run() {System.out.println("Fu run ....x = " + x);} } class Zi extends Fu{int x = 34;public void run() {int x = 56;// 由于方法中x变量,直接输出局部的x变量System.out.println("Zi run .... x = " + x);// 输出Zi类中的成员变量xSystem.out.println("Zi run .... x = " + this.x);// 输出Fu类中的成员变量xSystem.out.println("Zi run .... x = " + super.x);} } public class ExtendsDemo3 {public static void main(String[] args) {//Fu f = new Fu();//f.run();Zi z = new Zi();z.run();} }
5、super关键字
-
super可以在子类中调用父类中方法( super.父类方法名() )或者变量( super.变量名 )(不能私有)
-
在子类的构造方法中调用父类的构造方法,它只能写在子类构造方法中的第一行。super( );
在任何一个类的构造方法中如果没有手动书写this或者super语句调用构造方法,那么在这个类的构造方法的第一行中有个隐式的super( ) 语句在调用父类空参数的构造方法。
// 员工类
class Employee{private String name;private int age;private double salary;public Employee(String name, int age, double salary) {this.name = name;this.age = age;this.salary = salary;}}
// 程序员
class Coder extends Employee{public Coder(String name, int age, double salary) {super( name , age , salary );}
}
// 项目经理
class CoderManager extends Employee{public CoderManager(String name, int age, double salary) {super(name, age, salary);}}
public class ExtendsDemo4 {public static void main(String[] args) {Coder c = new Coder("张三" , 23 , 8000 );}
}
如果父类中没有空参数的构造方法,子类的构造方法中一定要手动添加super语句,显示指定调用父类有参数的构造方法。
6、超级父类
在Java中任何一个类如果没有直接书写它的父类,这时这个类一定会有一个超级父类Object。
Object类中定义的方法是所有类最共性的方法,任何子类都可以直接使用。
一般在项目中我们都需要去复写Object类中的equals、hashCode、toString三个方法。
7、final关键字
final它也是一个修饰符,它可以修饰类、方法(非构造方法)、变量(成员变量或局部变量)
7.1、final修饰的类
当我们在程序中定义一个类的时候,如果这个类不能被的别类继承,需要使用final修饰。
final修饰的类:最终类,不能再有子类。
final class Demo{ }
// 程序编译会出错
class Demo2 extends Demo{}
7.2、final修饰方法
一个类可以有子类(这个类能够被继承),类中有部分的方法是不允许子类复写的,这时可以使用final修饰这些不能被复写(重写、覆盖)的方法。
class Demo{public void run(){}// 它是一个最终方法public final void method(){}
}
class Demo2 extends Demo{// 编译报错,因为method无法被子类复写public void method(){}
}
7.3、final修饰变量
fianl修饰的变量,为常量,变量空间的数据永远无法改变。
class Demo{// 这个x是一个最终的变量private final int x = 12;public void setX( int x){this.x = x; } public void func(){// y也是一个最终的变量,无法改变y空间的值final int y = 23; }
}