• Java高级特性2


    1. static关键字

    1.1 类变量、类方法

    	/**
    	 * static关键字
    	 * 类变量不用实例化,直接类名.属性名就可以使用,是类的一部分,被所有这个类的实例化所共享,也可以叫做静态变量
    	 * 如果想让一个类的所有实例共享数据,就用类变量!
    	 * 
    	 * 实列变量,只是实例化后才能使用,属于实例化对象的一部分,不能公用
    	 * 
    	 * 使用范围
    	 * 可用static修饰属性、方法、代码块、内部类
    	 * 被修饰后的成员具备以下特点
    	 * 1.随着类的加载而加载(类加载后,静态方法或属性就可以使用了,类名.方法名)
    	 * 2.优先于对象存在,不用new就可以使用
    	 * 3.修饰的成员被所有对象所共享
    	 * 4.访问权限允许时,可不创建对象,直接被类调用
    	 * 
    	 * 注意:
    	 * 类变量,这种可以被所有实例化对象所共享的属性,使用起来要慎重,因为只要一改,所有类都能得到变化
    	 * 
    	 * 类方法:作为工具类的情况较多
    	 * static方法内部不能有this(也不能有super),因为this是针对对象的,static是类的,重载方法的方法需要同时为static或非static
    
    	 */
    

    1.2 工具类

    静态方法

    //判断字符串是否为空或null
    public class Utils {
    	public static boolean isEmpty(String s) {
    		boolean flag = false;
    		if (s ==null && s.equals("")){
    			flag = true;
    		}
    		return flag;
    	}
    	
    }
    
    //调用工具类
    Utils.isEmpty("test")
    

    1.3 单例 (Singleton)设计模式

    懒汉式单例设计模式

    public class Single1 {
    	private Single1() {}
    	/**
    	 * 懒汉式实例:第一次创建实例前为null,第一次创建实例后,创建,后面的都是同一个实例
    	 */
    	//私有的类变量,为null;
    	private static Single1 s1 = null;
    	
    	//公共的方法,如果s1为null,就创建实例,后面的就不用创建了
    	public static Single1 getInstance() {
    		if(s1 == null) {
    			s1 = new Single1();
    		}
    		return s1;
    	}
    }
    
    

    饿汉式单例设计模式

    public class Single {
    	/**
    	 * 单例设计模式:
    	 * 设计模式:就是在我们实际编程过程中,逐渐总结出的一些解决问题的套路
    	 * 单例设计模式:只有一个实例(实例化对象)在整个软件系统运行过程中,这个类只被实例化一次,以后无论在哪都只调用这一个实例
    	 */
    
    	//饿汉式
    	//私有的构造方法
    	private Single() {
    		
    	}
    	//私有的类变量,创建实例
    	private static Single s = new Single();
    	
    	//公共的方法,返回私有的类变量 
    	public static Single getInstance() {
    		return s;
    	}
    }
    

    懒汉式和饿汉式的区别

    		/**
    		 * 懒汉式和饿汉式的区别:
    		 * 就是什么时候new这个对象,懒汉式,是在第一次有人调用getlnstance方法时类new对象,
    		 * 以后再有人调用getinstance方法直接就返回第一次new好的对象
    		 * 
    		 * 饿汉式,是在类加载之后,还没有人调用的时候,就new好一个对象,以后无论谁来调用
    		 * getinstance方法都直接返回直接new好的那个对象
    		 */
    

    1.4 main方法

    		/**
    		 * main方法
    		 * public static void main(String[] args) {}
    		 * 由于java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public,
    		 * 又因为java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static的,
    		 * 该方法接收一个String类型的数组参数,
    		 * 该数组中保存执行java命令时传递给所运行的类的参数
    		 */
    

    2. 类的成员之初始化块

    2.1 非静态代码块

    //非静态代码块
    	{
    		System.out.println("这是非静态代码块中的方法1");
    	}
    	{
    		System.out.println("这是非静态代码块中的方法2");
    	}
    
    

    2.2静态代码块

    	//静态代码块
    	//复杂的属性,实例属性
    		static TestPer tp= new TestPer();
    	static {
    		//这里只能使用静态的属性和方法
    		age = 2;
    		showAge();
    		/**
    		 * 这程序的运行过程中,非静态代码块每次new对象都有重新执行
    		 * 静态代码块只执行一次
    		 */
    		System.out.println("这执行的是静态代码块");
    		//复杂的属性,可以通过代码块来初始化调用
    		tp.age = 1;
    		tp.name = "张三";
    	}
    

    2.3 匿名内部类

    		//匿名内部类
    		Person p = new Person() {//这就是一个Person的匿名子类,
    			/**
    			 * 构建了一个没有类名的Person的子类,也就是匿名的Person子类
    			 * 这两种类没有类名,就不能显示的new的方法创建对象,如果要是还要在构造器中初始化
    			 * 属性就没有办法了,这样情况就要用代码块{}来初始化工作
    			 */
    			{
    				//
    				super.name = "李四";
    			}
    			//从写方法
    			@Override
    			public void test() {
    				System.out.println("=========");
    			}
    		};//分号结尾
    		System.out.println(p.name);
    		p.test();
    

    2.4 总结

    1. 初始化块(代码块)作用:对Java对象进行初始化
    2. 程序的执行顺序:声明成员变量的默认值-显式初始化-多个初始化块依次被执行(同级别下按先后顺序执行)-构造器再对成员进行赋值操作
    3. 一个类中初始化块若有修饰符,则只能被static修饰,称为静态代码块(static block ),当类被载入时,类属性的声明和静态代码块先后顺序被执行,且只被执行一次。
    4. 非静态代码块:没有static修饰的代码块
      - 可以有输出语句。
      - 可以对类的属性声明进行初始化操作。
      - 可以调用静态和非静态的变量或方法。
      - 若有多个非静态的代码块,那么按照从上到下的顺序依 次执行。
      - 每次创建对象的时候,都会执行一次。且先于构造器执行
    5. 静态代码块:用static 修饰的代码块
      - 可以有输出语句。
      - 可以对类的属性声明进行初始化操作。
      - 不可以对非静态的属性初始化。即:不可以调用非静态的属 性和方法。
      - 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
      - 静态代码块的执行要先于非静态代码块。
      - 静态代码块只执行一次

    3. final关键字

    在Java中声明类、属性和方法时,可使用关键字final来修饰,表示“最终”。
    final标记的类不能被继承。提高安全性,提高程序的可读性
    final标记的方法不能被子类重写
    final标记的变量(成员变量或局部变量)即称为常量。名称大写,且只能被赋值一次。
    static final:全局常量

    4. 抽象类

    /**
     * 抽象类:
     * 1.用abstract关键字来修饰一个类时,这个类叫做抽象类
     * 2.用abstract来修饰一个方法时,该方法叫做抽象方法
     * 3.抽象方法:只有方法的声明,没有方法的实现。以分号结束:abstract int abstractMethod( int a );
     * 4.含有抽象方法的类必须被声明为抽象类
     * 5.抽象类不能被实例化。抽象类是用来作为父类被继承的,抽象类的子类必须重写父类的抽象方法,并提供方法体。若没有重写全部的抽象方法,仍为抽象类
     * 6.不能用abstract修饰属性、私有方法、构造器、静态方法、final的方法
     * @author Zw
     *
     */
    public abstract class Employee {
    	String id;
    	String name;
    	double salary;
    	//构造方法
    	public Employee() {}
    	//抽象方法
    	public abstract void work();
    }
    
    /**
     * 公司员工类,继承Employee类
     * 获取和设置员工信息
     *
     * @author Zw
     *
     */
    class CommonEmployee extends Employee{
    	@Override
    	public void work() {
    		System.out.println("这是一个员工.");
    	}
    	public void setEmployeeInfo(String id, String name, double salary) {
    		super.id = id;
    		super.name = name;
    		super.salary = salary;
    	}
    	public void getEmployeeInfo() {
    		System.out.println(id+"
    "+name+"
    "+salary);
    	}
    
    }
    
    /**
     * 领导类继承Employee
     * @author Zw
     *
     */
    class Manager extends Employee{
    	double bonus;
    	@Override
    	public void work() {
    		System.out.println("这是一个领导.");		
    	}
    	public void setManager(String id, String name, double salary, double bonus) {
    		super.id = id;
    		super.name = name;
    		super.salary = salary;
    		this.bonus = bonus;//子类的属性用this
    	}
    	public void getManager() {
    		System.out.println(id+"
    "+name+"
    "+salary+"
    "+bonus);
    	}
    
    }
    

    5. 模板模式的设计

    /**
     * 模板模式的设计:
     * 抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。
     * 解决的问题:
     * 1. 当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
     * 2. 编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式。
    
     * @author Zw
     *
     */
    public abstract class Template {
    	public abstract void run();
    	//提供子类调用的,计算run方法运行时间
    	public final void runTime() {
    		long start = System.currentTimeMillis();
    		run();
    		long end = System.currentTimeMillis();
    		System.out.println(end - start);
    	}
    }
    
    class testTemplate extends Template{
    	@Override
    	public void run() {
    		int a = 1;
    		for(int i=0; i<9999999;i++) {
    			a += i;
    		}		
    		
    	}
    }
    
    //模板设计模式,main中调用
    		Template tp = new testTemplate();
    		tp.runTime();//7毫秒
    

    6. 接口

    6.1 什么时候使用接口

    • 抽象类是对于一类事物的高度抽象,其中既有属性也有方法;

    • 接口是对方法的抽象,也就是一系列动作的抽象

    • 当需要对一类事物抽象的时候,应该使用抽象类,好形成一个法类

    • 当需要对一系列的动作(方法)抽象,就使用接口,需要使用这些动作的类去实现相应的接口

    6.2 接口的特点

    • 用interface来定义。

    • 接口中的所有成员变量都默认是由public static final修饰的。

    • 接口中的所有方法都默认是由public abstract修饰的。

    • 接口没有构造器。

    • 接口采用多层继承机制。

    • 实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类

    • 接口的主要用途就是被实现类实现

    • 与继承关系类似,接口与实现类之间存在多态性

    • 定义Java类的语法格式:先写extends,后写implements

    • 如果实现接口的类中没有实现接口中的全部方法,必须将此类定义为抽象类

    6.3 具体实例

    需求:
    teach类继承person类,并实现cook、sing接口

    代码

     * @author Zw
     * person 父类
     */
    public class Person1 {
    	String name;
    	int age;
    	int sex;
    	public void showInfo() {
    		
    	}
    	
    }
    
    /**
     * Cook接口
     * @author Zw
     */
    public interface Cook {
    	void cooking();
    }
    
    /**
     * Sing接口
     * @author Zw
     */
    public interface Sing {
    	void singing();
    }
    
    
    public class TeachCT extends Person1 implements Cook,Sing {//先继承后实现
    
    	String score;//老师自己的属性,科目
    	
    	@Override
    	public void showInfo() {
    		System.out.println("这是一个会唱歌做菜的老师的信息");
    		System.out.println(super.name+"
    "+super.age+"
    "+super.sex+"
    "+this.score);
    	}
    	public void setInfo() {
    		super.name = "李四";
    		super.age = 11;
    		super.sex = 1;
    		this.score = "物理";
    	}
    
    	@Override
    	public void singing() {//重写singing
    		System.out.println(super.name+"老师擅长美声唱法!");
    		
    	}
    	@Override
    	public void cooking() {//重写cooking
    		System.out.println(super.name+"老师擅长炒菜!");
    		
    	}
    }
    
    
    //调用
    //接口
    		TeachCT  tc = new TeachCT();
    		tc.setInfo();
    		tc.showInfo();
    		tc.cooking();
    		tc.singing();
    		
    		//接口对象的多态
    		Cook tp1 = new TeachCT();//可以转为实现接口的类型
    		tp1.cooking();//只能使用Cook类自己的属性和方法
    

    7. 工厂模式

    FactoryMethod模式是设计模式中应用最为广泛的模式,在面向对象的编程中,对象的创建工作非常简单,对象的创建时机却很重要。FactoryMethod解决的就是这个问题,它通过面向对象的手法,将所要创建的具体对象的创建工作延迟到了子类,从而提供了一种扩展的策略,较好的解决了这种紧耦合的关系。
    实例

    //父类接口
    public interface BMW {
    	//产品信息
    	void showInfo();
    }
    
    //宝马3系产品,实现接口
    class BMW1 implements BMW{
    
    	@Override
    	public void showInfo() {
    		System.out.println("这是BMW3系产品");		
    	}	
    } 
    
    //宝马5系产品
    class BMW5 implements BMW{
    
    	@Override
    	public void showInfo() {
    		System.out.println("这是BMW5系产品");		
    	}	
    } 
    
    //宝马7系产品
    class BMW7 implements BMW{
    
    	@Override
    	public void showInfo() {
    		System.out.println("这是BMW7系产品");		
    	}	
    } 
    
    
    //工厂模式
    /**
     * 汽车生产工厂接口
     * 通过工厂把new对象给隔离,通过产品的接口可以接受不同实际产品的实现类,
     * 实现类名改变不影响其他合作开发人员的编程
     * @author Zw
     *
     */
    public interface BMWFactory {
    	BMW productBMW();
    }
    /**
     * 实现具体车型的生产工厂
     * @author Zw
     *
     */
    
    class BMW3Factory implements BMWFactory{
    
    	@Override
    	public BMW productBMW() {
    		System.out.println("这是生产宝马3系车");
    		return new BMW1();//return 具体的产品
    	}	
    }
    
    class BMW5Factory implements BMWFactory{
    
    	@Override
    	public BMW productBMW() {
    		System.out.println("这是生产宝马3系车");
    		return new BMW5();
    	}	
    }
    
    class BMW7Factory implements BMWFactory{
    
    	@Override
    	public BMW productBMW() {
    		System.out.println("这是生产宝马3系车");
    		return new BMW7();
    	}	
    }
    
    //调用
    public class Test2 {
    	public static void main(String[] args) {
    		/**
    		 * 调用工厂方法
    		 */
    		BMW b3 = new BMW3Factory().productBMW();//new 具体车型的产品().方法()
    		b3.showInfo();
    		
    		BMW b5 = new BMW5Factory().productBMW();
    		b5.showInfo();
    		
    		BMW b7 = new BMW7Factory().productBMW();
    		b7.showInfo();
    	}
    }
    
  • 相关阅读:
    docker 镜像导入导出[转]
    部署coredns
    构建docker私有库
    怎么安装Docker CE 17( Centos 7)
    [转]使用tcpdump抓取HTTP包
    VLOOKUP函数使用
    有趣:256个class选择器可以干掉1个id选择器——张鑫旭
    算警示吧——此文来自张鑫旭(说说CSS学习中的瓶颈)
    不使用JavaScript让IE浏览器支持HTML5元素——张鑫旭
    CSS中width和height与盒子模型的关系
  • 原文地址:https://www.cnblogs.com/istart/p/11954601.html
Copyright © 2020-2023  润新知