第五章:Java_面向对象编程(三) 偏执的太偏执、 2022-07-12 04:57 172阅读 0赞 **目录:** > 1. static关键字 > > > * 单例模式 > 2. main()方法 > 3. 代码块 > 4. final关键字 > 5. 抽象:abstract > > > * 模板方法的设计模式 > 6. 接口interface > > > * 工厂方法的设计模式 > * 代理模式 > 7. 内部类 # 1.static关键字 # **1.static:静态的,**可以用来修饰属性、方法、*代码块(或初始化块)、*内部类 **2.static修饰属性(类变量):** 1.由类创建的所有的对象,都共用这一个属性 2.当其中一个对象对此属性进行修改,会导致其他对象对此属性的一个调用。vs 实例变量(非static修饰的属性,各个对象各自拥有一套副本) 3.类变量随着类的加载而加载的,而且独一份 4.静态的变量可以直接通过“类.类变量”的形式来调用 5.类变量的加载是要早于对象。所以当有对象以后,可以“对象.类变量”使用。但是”类.实例变量”是不行的。 6.类变量存在于静态域中。 **static修饰方法(类方法):** 1.随着类的加载而加载,在内存中也是独一份 2.可以直接通过“类.类方法”的方式调用 3.内部可以调用静态的属性或静态的方法,而不能调用非静态的属性或方法。反之,非静态的方法是可以调用静态的属性或静态的方法 ***静态的方法内是不可以有this或super关键字的!*** 注:静态的结构(static的属性、方法、代码块、内部类)的生命周期要早于非静态的结构,同时被回收也要晚于非静态的结构 ![这里写图片描述][SouthEast] public class TestCircle { public static void main(String[] args) { Circle c1 = new Circle(); Circle c2 = new Circle(2.3); System.out.println(c1); System.out.println(c2); System.out.println(Circle.getTotal()); } } class Circle{ private double radius; private static String info = "我是一个圆"; private int id;//编号 private static int init = 1001;//控制每个对象的id private static int total = 0;//记录创建了多少个对象 public Circle(){ this.id = init++; total++; } public Circle(double radius){ this.radius = radius; this.id = init++; total++; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public static String getInfo() { return info; } public static void setInfo(String info) { Circle.info = info; } public int getId() { return id; } public void setId(int id) { this.id = id; } public static int getTotal() { return total; } public static void setTotal(int total) { Circle.total = total; } @Override public String toString() { return "Circle [radius=" + radius + ", id=" + id + "]"; } public static void show(){ System.out.println(Circle.info); } public void desc(){ System.out.println(this.info); } } ## **设计模式之一:单例模式** ## 单例模式: > 解决的问题:如何只让设计的类只能创建一个对象 > 如何实现:饿汉式 & 懒汉式 //饿汉式1 class Bank{ //1.私有化构造器 private Bank(){} //2.创建类的对象,同时设置为private的,通过公共的来调用,体现封装性 //4.要求此对象也为static的 private static Bank instance = new Bank(); //3.此公共的方法,必须为static public static Bank getInstance(){ return instance; } } //饿汉式2 class Bank{ //1.私有化构造器 private Bank(){} //2.创建类的对象,同时设置为private的,通过公共的来调用,体现封装性 //4.要求此对象也为static的 private static Bank instance = null; static{ instance = new Bank(); } //3.此公共的方法,必须为static public static Bank getInstance(){ return instance; } } //懒汉式 class Bank{ private Bank(){} private static Bank instance = null; public static Bank getInstance(){ if(instance == null){ //可能存在线程安全问题的! instance = new Bank(); } return instance; } } # 2.main()方法 # public static void main(String[] args){ //方法体 } 1.main()是一个方法,是主方法,为程序的入口 2.权限修饰符:public protected 缺省 private —面向对象的封装性 3.对于方法来讲:static final abstract 4.方法的返回值:void / 具体的返回值类型(基本的数据类型 & 引用数据类型),方法内部一定要有return 5.方法名:命名的规则:xxxYyyZzz。给方法命名时,要见名之意 6.形参列表:同一个方法名不同的形参列表的诸多个方法间构成重载。 形参 & 实参—方法的参数传递机制:值传递 7.方法体:方法定义的是一种功能,具体的实现由方法体操作。 public class TestMain { public static void main(String[] args) { for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } } } 测试:在如上程序,为main函数传入两个String类型参数 操作:Eclipse代码中右键Run AS->Run configurations->选择Arguments 写入:哈哈 呵呵 # 3.代码块 # > 代码块:是类的第4个成员 > 作用:用来初始化类的属性 > 分类:只能用static来修饰。 **静态代码块:** 1.里面可以有输出语句 2.随着类的加载而加载,而且只被加载一次 3.多个静态代码块之间按照顺序结构执行 4.静态代码块的执行要早于非静态代码块的执行。 5.静态的代码块中只能执行静态的结构(类属性,类方法) **非静态代码块:** 1.可以对类的属性(静态的 & 非静态的)进行初始化操作,同时也可以调用本类声明的方法(静态的 & 非静态的) 2.里面可以有输出语句 3.一个类中可以有多个非静态的代码块,多个代码块之间按照顺序结构执行 4.每创建一个类的对象,非静态代码块就加载一次。 5.非静态代码块的执行要早于构造器 **关于属性赋值的操作:** ①默认的初始化 ②显式的初始化或代码块初始化(此处两个结构按照顺序执行) ③构造器中; ——–以上是对象的属性初始化的过程——— ④通过方法对对象的相应属性进行修改 eg: public class TestDaima { public static void main(String[] args) { Person p1 = new Person(); p1.getId(1002); System.out.println(p1); } } class Person{ String name; int id = 1000; public Person() { System.out.println("无参构造器"); this.id = 1001; } public Person( int id){ this.id = id; } //非静态代码块 { id = 10003; System.out.println("非静态代码块1"); } { id = 10004; System.out.println("非静态代码块2"); } public void getId(int numeber){ System.out.println("show()方法调用"); id = numeber; } @Override public String toString() { return "Person [name=" + name + ", id=" + id + "]"; } } 结果: ![这里写图片描述][SouthEast 1] 过程: > 1.默认初始化 name = null, id = 0 > > 2.(因为显示初始化在前,所以)显示初始化 id = 1000 —-> 静态代码块1:id = 10003—-> 静态代码块2:id=10004 > > 3.构造器:调用无参构造器Person() id = 1001; > > 4.通过方法对对象相应属性进行修改:调用getId() -> id:1002 # 4.final关键字 # final:最终的 ,可以用来修饰类、属性、方法 1.final修饰类:这个类就不能被继承。如:String类、StringBuffer类、System类 2.final修饰方法:不能被重写。如:Object类的getClass() 3.final修饰属性:此属性就是一个常量,一旦初始化后,不可再被赋值。习惯上,常量用大写字符表示。 此常量在哪里赋值:①此常量不能使用默认初始化 ②可以显式的赋值、代码块、构造器。 变量用static final修饰:全局常量。比如:Math 类的PI 注:与finally finalize()区分开 class D{ final int I = 12; final double PI; final String NAME; public void m1(){ System.out.println(I); // I = 10; } { PI = 3.14; } public D(){ NAME = "DD"; } public D(String name){ this(); //NAME = name; } } # 5.抽象:abstract # 重点! abstract:抽象的,可以用来修饰类、方法 **1.abstract修饰类:抽象类** 1)不可被实例化 2)抽象类有构造器 (凡是类都有构造器) 3)抽象方法所在的类,一定是抽象类。 4)抽象类中可以没有抽象方法。 当我们设计一个类,不需要创建此类的实例时候,就可以考虑将其设置为抽象的,由其子类实现这个类的抽象方法以后,就行实例化 **2.abstract修饰方法:抽象方法** 1)格式:没有方法体,包括\{\}.如:public abstract void eat(); 2)抽象方法只保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写此抽象方法。 3)若子类继承抽象类,并重写了所有的抽象方法,则此类是一个”实体类”,即可以实例化 4)若子类继承抽象类,没有重写所有的抽象方法,意味着此类中仍有抽象方法,则此类必须声明为抽象的! ## **设计模式之二:模板方法设计模式** ## //模板方法设计模式 public class TestTemplate { public static void main(String[] args) { new SubTemplate().spendTime(); } } abstract class Template { public abstract void code(); public void spendTime() { long start = System.currentTimeMillis(); this.code(); long end = System.currentTimeMillis(); System.out.println("花费的时间为:" + (end - start)); } } class SubTemplate 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; } } } # 6. 接口interface # 接口(interface) 是与类并行的一个概念 ![这里写图片描述][SouthEast 2] 1.接口可以看做是一个特殊的抽象类。是常量与抽象方法的一个集合,不能包含变量、一般的方法。 ![这里写图片描述][SouthEast 3] 常量:所有的常量都用public static final修饰 抽象方法:所有的都用public abstract修饰 2.接口是没有构造器的。 3.接口定义的就是一种功能。此功能可以被类所实现(implements)。比如:class CC extends DD implements AA 4.实现接口的类,必须要重写其中的所有的抽象方法,方可实例化。若没有重写所有的抽象方法,则此类仍为一个抽象类 5.类可以实现多个接口。—-java 中的类的继承是单继承的 6.接口与接口之间也是继承的关系,而且可以实现多继承 `5, 6描述的是java中的继承的特点。` 7.接口与具体的实现类之间也存在多态性 **8.面向接口编程的思想:** ![这里写图片描述][SouthEast 4] **9.接口用法总结** ![这里写图片描述][SouthEast 5] ## **设计模式之三:工厂方法的设计模式** ## //接口的应用:工厂方法的设计模式 public class TestFactoryMethod { public static void main(String[] args) { IWorkFactory i = new StudentWorkFactory(); i.getWork().doWork(); IWorkFactory i1 = new TeacherWorkFactory(); i1.getWork().doWork(); } } interface IWorkFactory{ Work getWork(); } class StudentWorkFactory implements IWorkFactory{ @Override public Work getWork() { return new StudentWork(); } } class TeacherWorkFactory implements IWorkFactory{ @Override public Work getWork() { return new TeacherWork(); } } interface Work{ void doWork(); } class StudentWork implements Work{ @Override public void doWork() { System.out.println("学生写作业"); } } class TeacherWork implements Work{ @Override public void doWork() { System.out.println("老师批改作业"); } } ## 设计模式之四:代理模式(静态代理) ## //接口的应用:代理模式(静态代理) public class TestProxy { public static void main(String[] args) { Object obj = new ProxyObject(); obj.action(); } } interface Object{ void action(); } //代理类 class ProxyObject implements Object{ Object obj; public ProxyObject(){ System.out.println("代理类创建成功"); obj = new ObjctImpl(); } public void action(){ System.out.println("代理类开始执行"); obj.action(); System.out.println("代理类执行结束"); } } //被代理类 class ObjctImpl implements Object{ @Override public void action() { System.out.println("=====被代理类开始执行======"); System.out.println("=====具体的操作======"); System.out.println("=====被代理类执行完毕======"); } } # 7.内部类 # 类的第5个成员:内部类 1.相当于说,我们可以在类的内部再定义类。外面的类:外部类。里面定义的类:内部类 2.内部类的分类:成员内部类(声明在类内部且类的方法外的) vs 局部内部类(声明在类的方法里) **3.成员内部类:** 3.1是外部类的一个成员:①可以有修饰符(4个)②static final ③可以调用外部类的属性、方法 3.2具体类的特点:①abstract ②还可以在其内部定义属性、方法、构造器 //成员内部类 public class OutInner { public static void main(String[] args) { //创建静态内部类的对象,可以直接通过外部类调用内部类的构造器 Person.Dog d = new Person.Dog(); //不是这样写的:Person.new Dog() //创建非静态的内部类的对象,必须先创建外部类的对象,通过外部类的对象调用内部类的构造器 Person p = new Person(); Person.Bird b = p.new Bird(); //不是这样写的:new Bird() } } public class OutInner { public static void main(String[] args) { //创建静态内部类的对象,可以直接通过外部类调用内部类的构造器 Person.Dog d = new Person.Dog(); //不是这样写的:Person.new Dog() //创建非静态的内部类的对象,必须先创建外部类的对象,通过外部类的对象调用内部类的构造器 Person p = new Person(); Person.Bird b = p.new Bird(); //不是这样写的:new Bird() b.info(); b.setName("王五"); } } class Person{ String name = "张三"; int age; //成员内部类 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 class Dog{ } public void show(){ System.out.println("外部类,哈哈哈"); } } **4.局部内部类:** //局部内部类 class Outer{ //局部内部类,如下使用方式 public void method(){ class InnerClass{ } } //常常使用一个方法,使其返回值作为某个类或接口的对象,而这个类或接口在方法内部创建 //使用方式一 public Comparable getComparable(){ //1.创建一个实现Comparabla接口的类:局部内部类 class MyComparable implements Comparable{ @Override public int compareTo(Object o) { return 0; } } //2.返回一个实现类的对象 return new MyComparable(); } //使用方式二 public Comparable getComparable1(){ //返回一个实现Comparable接口的匿名内部类的对象 return new Comparable(){ @Override public int compareTo(Object o) { return 0; } }; } } 5.关于内部类,大家掌握三点: ①如何创建成员内部类的对象(如:创建Bird类和Dog类的对象) ②如何区分调用外部类、内部类的变量(尤其是变量重名时) ③局部内部类的使用 (见TestInnerClass1.java) [SouthEast]: /images/20220711/2a97a852f247469bb9af5ea41f5e689d.png [SouthEast 1]: /images/20220711/4af768786f464d769905214ac0601a70.png [SouthEast 2]: /images/20220711/516850812adb47e7ac3489cef82f887c.png [SouthEast 3]: /images/20220711/f7a6b6bbaf924350a2931c701d1581ba.png [SouthEast 4]: /images/20220711/cfe02a70b0b24b2d964f5ebfdddf7c1e.png [SouthEast 5]: /images/20220711/42632615ffb54939aa052f20745de70f.png
还没有评论,来说两句吧...