static关键字
static是静态的意思,可以用来修饰成员变量、成员方法。
static修饰成员变量之后称为静态成员变量(类变量),修饰方法之后称为静态方法(类方法)。
static修饰后的成员变量,可以被类的所有对象共享(访问、修改)。
public class User{
static String name;
int age;
}
User.name = "张三";
User u = new User();
u.age = 18;
System.out.println(User.name); //张三
System.out.println(u.age); //18
注意点:
静态成员方法(有static修饰,归属于类),建议用类名访问,也可以用对象访问
实例成员方法(无static修饰,归属于对象),只能用对象触发访问。
表示对象自己的行为的,且方法中需要访问实例成员的,则该方法必须申明成实例方法。
如果某方法是以执行一个共用功能为目的,则可以申明成静态方法。
静态方法只能访问静态的成员,不可以直接访问实例成员。
实例方法可以访问静态的成员,也可以访问实例成员。
静态方法中是不可以出现this关键字的
package com.itheima.d1_static;
public class Car {
private String name;
static void run(){
System.out.println("车跑的很快");
//System.out.println(this); //报错,this不能出现在静态方法中
}
public static void main(String[] args) {
run(); //直接访问
Car.run(); //类名访问
Car c = new Car();
c.name = "奔驰";
//name; //报错
//Car.name; //报错
c.run(); //实例对象访问静态方法
}
}
工具类
工具类是什么,有什么好处?
内部都是一些静态方法,每个方法完成一个功能
一次编写,处处可用,提高代码的重用性。
一般可以把工具类的构造器私有化处理,因为工具类不需要创建对象。
public class codeVerify{
private codeVerify(){ //构造器私有化处理,因为工具类不需要创建对象。
}
}
代码块概述
在Java类下,使用 { } 括起来的代码被称为代码块 。
静态代码块:
需要通过static关键字修饰,随着类的加载而加载,并且自动触发、只执行一次,在类加载的时候做一些静态数据初始化的操作,以便后续使用。
package d3_static_code;
public class StaticDemo {
//静态代码块,属于类,与类一起优先加载一次,自动执行触发
static{
System.out.println("静态代码块被执行了");
}
public static void main(String[] args) {
//理解静态代码块
System.out.println("mian方法被执行了");
}
/**
* 静态代码块被执行了
* mian方法被执行了
*
* */
}
构造代码块:
每次创建对象,调用构造器执行时,都会执行该代码块中的代码,并且在构造器执行前执行,用于初始化实例资源,但几乎不用
如果要在启动系统时对静态资源进行初始化,则建议使用静态代码块完成数据的初始化操作。
设计模式
开发中经常遇到一些问题,一个问题通常有n种解法的,但其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,称之为设计模式。
单例模式
可以保证系统中,应用该模式的这个类永远只有一个实例,即一个类永远只能创建一个对象。
例如任务管理器对象我们只需要一个就可以解决问题了,这样可以节省内存空间。
饿汉单例设计模式:
定义一个类,把构造器私有。
定义一个静态变量存储一个对象。
//Test1.java
package d4_static_demo;
public class Test1 {
public static void main(String[] args) {
SingLeInstance s1 = SingLeInstance.instance;
SingLeInstance s2 = SingLeInstance.instance;
System.out.println(s1==s2); //true
}
}
--------------------分割线------------------------
//SingLeInstance.java
package d4_static_demo;
public class SingLeInstance {
//1.私有化构造器
private SingLeInstance(){
}
//2.静态变量储存一个对象
//这个对象只能是一个,所以定义静态成员变量
public static SingLeInstance instance = new SingLeInstance();
}
懒汉单例模式:
在真正需要该对象的时候,才去创建一个对象(延迟加载对象)。
定义一个类,把构造器私有
定义一个静态变量存储一个对象
提供一个返回单例对象的方法
//Test2.java
package d4_static_demo;
public class Test2 {
public static void main(String[] args) {
SingleInstance1 s1 =SingleInstance1.getInstance();
SingleInstance1 s2 =SingleInstance1.getInstance();
System.out.println(s1==s2); //true
}
}
---------------------------
//SingleInstance1.java
package d4_static_demo;
public class SingleInstance1 {
private SingleInstance1(){
//1.私有化构造器
}
private static SingleInstance1 instance1; //2.定义一个变量储存一个对象
//静态成员只加载一次,只有一份
//3.提供一个方法,对外返回单例对象
public static SingleInstance1 getInstance(){
if(instance1==null){ //没有对象创建一个对象
instance1 = new SingleInstance1();
}
return instance1; //有对象直接返回即可
}
}
继承
Java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起父子关系,当子类继承父类后,就可以直接使用父类公共的属性和方法
子类的方法一般比父类的方法强大
子类不能继承父类的私有成员,子类可以共享父类静态成员
一个子类只能继承一个父类,不支持多继承,但支持多层继承
Object是祖宗类,所有类要么直接继承Object类,要么默认继承Object
//Test.java
package d5_extends.Test;
public class Test {
public static void main(String[] args) {
//目标:认识继承使用继承
Student s = new Student();
s.die();
s.run();
//s.eat(); //私有化方法不能被继承
s.study(); //子类自己的方法
}
}
------------------------------------
//People.java 父类
package d5_extends.Test;
public class People {
public void run(){
System.out.println("人会跑");
}
private void eat(){
System.out.println("吃饭");
}
protected void die(){
System.out.println("人都会死");
}
}
------------------------------
//Student.java 子类
package d5_extends.Test;
public class Student extends People{ //继承People类
public void study(){
System.out.println("学生应该好好学习");
}
}
继承后成员变量的访问特点:就近原则
如果需要再子类中使用父类的属性需要使用super关键字
package d7_extends_test;
public class Test {
public static void main(String[] args) {
Dog g = new Dog();
g.run(); //狗跑的很快
g.getName(); //动物名
}
}
class Animal{
public void run(){
System.out.println("动物可以跑");
}
public void getName(){
System.out.println("动物名");
}
}
class Dog extends Animal{
public void run() {
System.out.println("狗跑的很快");
}
public void getName(){
super.getName(); //找父类中的getName
}
}
方法重写
子类写一个与父类申明一样的方法覆盖父类的方法。
@Override注解可以校验重写是否正确
重写方法的名称和形参列表应该与被重写方法一致。
私有方法不能被重写。
子类重写父类方法时,访问权限必须大于或者等于父类被重写的方法的权限。
package d7_extends_test;
import org.w3c.dom.ls.LSOutput;
public class Test1 {
public static void main(String[] args) {
newPhone n = new newPhone();
n.call(); //先调用父类的方法,再执行自己的方法
n.senMsg(); //先调用父类的方法,再执行自己的方法
}
}
class phone{
public void call(){
System.out.println("打电话");
}
public void senMsg(){
System.out.println("发信息");
}
}
class newPhone extends phone{
//重写的方法
//重写方法的名称和形参列表应该与被重写方法一致。
@Override //加上这个方法必须是重写的
public void call(){
super.call(); //先使用父类的基本功能
System.out.println("其他功能"); //定义自己的功能
}
//重写的方法
//重写方法的名称和形参列表应该与被重写方法一致。
@Override
public void senMsg(){
super.senMsg(); //先使用父类功能
System.out.println("自己的功能"); //定义自己的功能
}
}