Java-day09(单例设计模式,main方法,final关键字,抽象(abstract),模板方法设计模式,接口(interface),工厂方法设计模式,代理设计模式,内部类)

单例设计模式,main方法,final关键字,抽象(abstract),模板方法设计模式,接口(interface),工厂方法设计模式,代理设计模式,内部类

设计模式(23种)

在大量实践总结和理论结合后优化的代码结构,编程风格,及解决问题的思考方式。

单例设计模式

对于某个类只能存在一个对象实例,并该类只提供一个取得其对象实例的方法。
饿汉式

  • 将类的构造方法的访问权限设置为private

  • 在类的内部创建一个类的实例

  • 私有化此对象(实例),通过公共的方法来调用

  • 此公共的方法,只能通过类来调用,因此设置为static,同时类的实例也必须为static声明的

class Sing{
	private Sing(){      
	}
	private static Sing s = new Sing();
	public static Sing gets(){
		return s;
	}
}

懒汉式:可能存在线程安全问题

  • 将类的构造方法的访问权限设置为private

  • 在类的内部先不创建类的实例(private 类名 实例名 = null

  • 通过公共的方法来调用,判断实例名是否为空,为空就创建实例(实例名 = new 类名()),返回实例

class Sing{
	private Sing(){               
	}
	private static Sing s = null;
	public static Sing gets(){
		if(s == null){
			s = new Sing();
		}
		return s;
	}
}

main()方法

  • 即可当作程序的入口,也可当作一般的方法
public class Test{
	public static void main(String[] args) {   
		for(int i = 0;i < args.length;i++){
			System.out.println(args[i]);
		}
	}
	
}

命令行运行结果(编译–运行)
Java-day09(单例设计模式,main方法,final关键字,抽象(abstract),模板方法设计模式,接口(interface),工厂方法设计模式,代理设计模式,内部类)_第1张图片

类成员:初始化块

静态代码块

  • 可以有输出语句

  • 可以对类的属性,类的声明进行初始化操作

  • 不可以对非静态的属性初始化(不可以调用非静态的属性和方法)

  • 若有多个静态的代码块,按照从上到下的顺序依次执行

  • 静态代码块的执行要先于非静态代码块

  • 静态代码块只执行一次

非静态代码块

  • 可以有输出语句

  • 可以对类的属性,类的声明进行初始化操作

  • 可以对静态的属性初始化(可以调用静态的属性和方法)

  • 若有多个非静态的代码块,按照从上到下的顺序依次执行

  • 每次创建对象时,都会执行一次,且先于构造器执行

属性赋值顺序

  1. 默认的初始化
  2. 显式的初始化或代码块初始化(若有多个,按顺序执行)
  3. 构造器中
  4. 通过方法对对象的属性进行修改

例:

public class Test1{
	public static void main(String[] args) {      
		Person p1 = new Person();
		System.out.println(p1);
		System.out.println();
		Person p2 = new Person();
		System.out.println(p2);
	}
	
}
class Person{
	private int age;
	static private String name;

	public Person(){
		super();
		System.out.println("空参构造器");
	}
	//初始化块(或代码块)
	{//非静态初始化块
		age = 18;
		name = "SSS";
		System.out.println("你好!" + name);   

	}
	static{//静态初始化块
		name = "AAA";
		System.out.println("下午好!" + name);

	}

	
	public Person(String name,int age){
		super();
		this.age = age;
		this.name =name;
	}

	public  int getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}	
	public  int getAge() {
		return age;
	}
	
	public  void setAge(int age) {
		this.age = age;
	}	
	//重写toString()方法
	public String toString(){
		return "Person:name " + name + " age: " + age;
	}
}

Java-day09(单例设计模式,main方法,final关键字,抽象(abstract),模板方法设计模式,接口(interface),工厂方法设计模式,代理设计模式,内部类)_第2张图片

关键字:final

在Java中声明类,属性,方法时,可使用关键字final来修饰,表示"最终"。

  • final标记的类不能被继承(提高安全性,可读性),如:String类,System类等
  • final标记的方法不能被子类重写,如Object类的getClass()
  • final标记的变量(成员变量或局部变量)即成为常量。名称大写,且只能被赋值一次(不支持默认初始化,支持显式赋值,代码块,构造器)
  • final标记的变量必须在声明的同时或在每个构造方法中或代码块中显式赋值,才能使用,如final double PI = 3.14

例:

public class TestFinal{
	public static void main(String[] args) {              
		Person p1 = new Person();
		System.out.println(p1);
	}
}
final class Person{
	private final int Age = 80;//常量
	static private String name;
	final int Id;

	public Person(){
		super();
		System.out.println("空参构造器");
	}
	{
	Id = 1002;
	}
	//重写toString()方法,且设置为final(即此方法本次修改后无法再被重写)
	public final String toString(){
		return "Person:name " + name + " Age: " + Age + " Id: " + Id;
	}
}

全局常量:用staticfinal修饰的变量
练习
Java-day09(单例设计模式,main方法,final关键字,抽象(abstract),模板方法设计模式,接口(interface),工厂方法设计模式,代理设计模式,内部类)_第3张图片

题一:final已赋值最终的x值,不能再进行修改
题二:final修饰的对象,对象的属性可以进行修改

抽象(abstract)

abstract可以修饰类,方法,不能修饰属性,构造器,不能与`private,final,static共用

抽象类(abstract class)

  • 将父类设计得非常抽象,以至于它没有具体的实例,这样的类叫做抽象类
  • 抽象类是用来模型化那些父类无法确定全部实现,而由子类提供具体实现的对象类
  • 不可被实例化
  • 抽象类有构造器(凡是类都要构造器)
  • 抽象方法所在类一定是抽象类
  • 抽象类可以没有抽象方法

抽象方法

  • 格式:没有方法体,包括{}。如:public abstract void info();

  • 抽象方法只保留功能,具体的执行,交给子类去重写此方法

  • 若子类继承抽象类,并重写所有抽象方法,则此类是一个"实体类",即可以实例化

  • 若子类继承抽象类,没有重写所有抽象方法,则此类中仍有抽象方法,即此类必须声明为抽象类

例:

public class Test{
	public static void main(String[] args) {      
		Person p1 = new Person();
		p1.info();
		Student s1 = new Student();
		s1.info();
		
		}
}
abstract class Person{
	String name;
	int age;
	public Person(){

	}
	public Person(String name,int age){
		this.age = age;
		this.name = name;
	}
	public abstract void info();//定义了功能,但没实现
}
class Student extends Person{ 
	public Person(){

	}
	public void info(){//实现了功能
		System.out.println("学生要吃饭了");
	}
}

练习
题一

public class Test3{
	public static void main(String[] args) {    
		Employee m1 = new Manager();
		m1.work();
		CommonEmployee c1 = new CommonEmployee();
		c1.work();
	}
	
}
abstract class Employee{ 
	private String name;
	private int id;
	private double salary;
	//抽象方法
	public abstract void work();

	public Employee(){

	}
	public Employee(String name){
	}
}
//管理者
class Manager extends Employee{
	private double bonus;
	public void work(){
		System.out.println("管理者:开始上班了!");
	}
}
//一般员工
class CommonEmployee extends Employee{
	public void work(){
		System.out.println("工人:可以上班摸鱼了!");
	}
}

结果如图
Java-day09(单例设计模式,main方法,final关键字,抽象(abstract),模板方法设计模式,接口(interface),工厂方法设计模式,代理设计模式,内部类)_第4张图片

模板方法设计模式(TemplateMethod)

抽象类作为多个子类的通用模板,子类在父类的基础上进行扩展,改造,子类总体上会保留抽象类的行为方式
例:

public class Test4{
	public static void main(String[] args) { 
		new Stemplate().spendTime();
		}
	}
	
abstract class Template{ 
	public abstract void code();
	public void spendTime(){
		long start = System.currentTimeMillis();
		code();
		long end = System.currentTimeMillis();
		System.out.println("花费时间: " + (end - start));
	}
}

class Stemplate extends Template{
	public void code(){
		boolean flag = false;
		for(int i = 2;i < 10000;i++){
			for(int j = 2;j <= Math.sqrt(i);j++){
				if(i % j == 0){
					flag = true;
					break;
				}
			}
			if(!flag){
				System.out.println(i);
			}
			flag = false;
		}
	}
}

接口(interface)

  • 接口是抽象方法和常量值的定义的集合,与类并行的一个概念

  • 本质上,接口是一种特殊的抽象类,这种抽象类中只包含常量(在接口中,所有的常量都用public static final修饰,故可省略)和方法(在接口中,所有的方法都用public abstract修饰,故可省略)的定义,没有变量和方法的实现。

  • 接口没有构造器

  • 实现接口类:

class Templates extends Time implements Template,Templated

(Templates继承 Time类,实现Template,Templated接口)

  • 一个类可以实现多个接口,一个接口可以继承其他接口

  • 实现接口的类,必须重写所有抽象方法,才可以实例化;否则,仍为抽象类

  • 类与类之间继承关系(单),接口之间仍为继承关系(多)

例:

public class Test5{
	public static void main(String[] args) {
		System.out.println(Template.P);
		System.out.println(Template.I);
		}
	}
	
interface Template{
	//常量
	public static final int I = 18;
	String P =  "你好!";
	//抽象方法
	public abstract void spendTime();
	void SpendTime();
}
class Templates implements Template{
	public void spendTime(){
		System.out.println("kdkd");

	}
	public void SpendTime(){
	}
}
interface AA{
	
	void AAD();

}
interface BB extends AA,Template{
	void BBOS();

}
class CC implements BB{
	//Template接口的实现
	public  void spendTime(){

	}
	public void SpendTime(){

	}
	//AA接口的实现
	public void AAD(){

	}
	//BB接口的实现
	public void BBOS(){

	}
}

接口的多态性

接口与具体的实现类之间存在多态性
例:

public class Test6{
	public static void main(String[] args) {           
		Duck duck = new Duck();
		Test6.test(duck);
		Test6.test1(duck);
		Test6.test2(duck);


	}
	public static void test(Runner r){//Runner r = new Duck();
		r.run();//虚拟方法调用(实际执行的是对象的实体方法)
	}
	public static void test1(Swimmer s){
		r.swim();
	}
	public static void test2(Flier f){
		r.fly();
	}
	
}
interface Runner{
	public abstract void run();
}
interface Swimmer{ 
	void swim();
}
interface Flier{
	void fly();
}

class Duck implements Runner,Swimmer,Flier{
	public void run(){
		System.out.println("鸭子会跑"); 
	}
	public void swim(){
		System.out.println("鸭子会游泳");
	}
	public void fly(){
		System.out.println("鸭子也能飞");
	}
}

接口总结

  • 通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系
  • 通过接口可以指明多个类需要实现的方法,一般用定义对象的扩张功能
  • 接口主要用来定义规范,解除耦合关系

工厂方法的设计模式(接口)

Java-day09(单例设计模式,main方法,final关键字,抽象(abstract),模板方法设计模式,接口(interface),工厂方法设计模式,代理设计模式,内部类)_第5张图片

public class Test7{
	public static void main(String[] args) {     
		WorkFactory w = new StudentWorkFactory();
		w.getWork().doWork();
	}
	
}
//定义夺取对象的接口,实现获取相应的对象
interface WorkFactory{
	Work getWork();
}
class StudentWorkFactory implements WorkFactory{
	public Work getWork(){
		return new StudentWork();
	}
}
class TeacherWorkFactory implements WorkFactory{
	public Work getWork(){
		return new TeacherWork();
	}
}

//定义工作,实现获取相应的工作
interface Work{
	void doWork();
}
class StudentWork implements Work{ 
	public void doWork(){
		System.out.println("学生工作:做作业");
	}
}
class TeacherWork implements Work{
	public void doWork(){
		System.out.println("老师工作:教学生");
	}
}

代理模式(proxy)(接口)

为其他对象提供一种代理以控制对这个对象的访问
Java-day09(单例设计模式,main方法,final关键字,抽象(abstract),模板方法设计模式,接口(interface),工厂方法设计模式,代理设计模式,内部类)_第6张图片

例:

public class Test8{
	public static void main(String[] args) {   
		Object o = new ProxyObject();
		o.action();
	}
}
interface Object{
	void action();
}
//代理类
class ProxyObject implements Object{
	Object object;
	public ProxyObject(){
		System.out.println("代理创建成功");
		object = new ObjectImpl();
		
	}
	public void action(){
		System.out.println("======代理执行中========");
		object.action();
		System.out.println("======代理执行完毕========");
	}

}
//被代理类
class ObjectImpl implements Object{
	public void action(){
		System.out.println("======任务执行中========");
		System.out.println("======任务执行完毕========");

	}
}

练习
Java-day09(单例设计模式,main方法,final关键字,抽象(abstract),模板方法设计模式,接口(interface),工厂方法设计模式,代理设计模式,内部类)_第7张图片

public class Test9{
	public static void main(String[] args) {    
		CompareCircle c1 = new CompareCircle(3.3);
		CompareCircle c2 = new CompareCircle(2.3);
		CompareCircle c3 = new CompareCircle(3.3);
		CompareCircle c4 = new CompareCircle(4.3);

		int i1 = c1.compareTo(c3);
		int i2 = c2.compareTo(c4);
		int i3 = c1.compareTo(new String());
		System.out.println(i1);//0
		System.out.println(i2);//-1
		System.out.println(i3);//非CompareCircle对象,无法比较
		
	}
	
}
interface CompareObject{
	int compareTo(Object o);
}

class Circle{
	private double radius;
	public Circle(){
		super();
	}
	public Circle(double radius){
		super();
		this.radius = radius;
	}
	public double getRadius(){
		return radius;
	}
	public void setRadius(double radius){
		this.radius = radius;
	}
}

class CompareCircle extends Circle implements CompareObject{
	public CompareCircle(double radius) {
		super(radius);
	}
	public int compareTo(Object o){
		if(this == o){
			return 0;
		}else if(o instanceof CompareCircle){
			CompareCircle c = (CompareCircle)o;
			if(this.getRadius() > c.getRadius()){
				return 1;
			}else if(this.getRadius() < c.getRadius()){
				return -1;
			}else {
				return 0;
			}
		}else{
			throw new RuntimeException("非CompareCircle对象,无法比较");
		}

	}

}

类成员:内部类

  • 在Java中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类
  • 内部 一般用在定义它的类或者语句块之内,在外部引用它时必须给出完整的名称
  • 内部类的名字不能与包含它的类名相同
  • 外部类要访问内部类中的成员需要:内部类.成员内部类.对象.成员

分类

成员内部类

  • 外部类的一个成员,可以有修饰符(4个),也可以用static,final修饰

  • 特点:可以用abstract修饰,可以在其内部定义属性,方法,构造器

public class Test10{
	public static void main(String[] args) {        
		//创建静态内部类的对象
		Person.Dog d = new Person.Dog();
		//创建非静态内部类的对象(先创建外部类的对象,通过外部类的对象调用内部类的构造器)
		Person p = new Person();
		Person.Bird b = p.new Bird();
		b.info();
		b.setName("家雀");
		
	}
	
}
class Person{
	String name = "李华";
	int age;
	//成员内部类(非static)
	class Bird{
		String name = "大嘴雀";
		int id;
		public Bird(){

		}
		public void setName(String name){
			System.out.println(name);//家雀 
			System.out.println(this.name);//大嘴雀
			System.out.println(Person.this.name);//李华

		}
		public void info(){
			show();
		}
	}	
	//成员内部类(static)
	static class Dog{

	}
	public void show(){
		System.out.println("开始你的表演!");

	}
}

局部内部类(不说修饰符),匿名内部类

  • 常常使用一个方法,使其返回值为某个类或接口的对象。而这个类或接口在方法内部创建
class AA{
  //局部内部类(使用较少)
	//方法一
	public   Comparable getComparable(){  
		//1.创建一个实现Comparable接口的类:局部内部类
		class MyComparable implements Comparable{
			public int compareTo(java.lang.Object o){
				return 0;
			}
		}//2.返回一个实现类的对象
		return new MyComparable();
	}
	//方法二
	public Comparable getComparable1(){
		//返回一个实现Comparable接口的匿名内部类的对象
		return new Comparable() {
			public int compareTo(java.lang.Object o){
				return 0;
			}
		};
	}  
}

例:

public class Test11{
	public static void main(String[] args) {   
		Test11 t = new Test11();
		//方式一:创建实现Prdoct接口的类的对象,并将对象传入方法中(简单,可读性强)
		Book book = new Book();
		t.show(book);
		//方式二:创建实现Prdoct接口的匿名类的对象
		Prdoct p = new Prdoct(){
			public void getName(){
				System.out.println("红米笔记本");
			}
			public void getPrice(){
				System.out.println("$2500");
			}			
		};

		//方式三:创建实现Prdoct接口的匿名类的匿名对象
		t.show(new Prdoct() {
			public void getName(){
				System.out.println("苹果笔记本");
			}
			public void getPrice(){
				System.out.println("$15000");
			}			
		});

	}
	public void show(Prdoct p){
		p.getName();
		p.getPrice();
	}
}
interface Prdoct{
	void getName();
	void getPrice();
}
class Book implements Prdoct{
	public void getName(){
		System.out.println("笔记本");
	}
	public void getPrice(){
		System.out.println("$5000");
	}
}

终于结束了面向对象的学习了!
Java-day09(单例设计模式,main方法,final关键字,抽象(abstract),模板方法设计模式,接口(interface),工厂方法设计模式,代理设计模式,内部类)_第8张图片

感谢大家的支持,关注,评论,点赞!
参考资料:
尚硅谷宋红康20天搞定Java基础中部

你可能感兴趣的:(Java,java,设计模式,开发语言)