商城网站建设论文,wordpress 查看大图,企业网站首页应如何布局,项目开发的五个阶段面向对象编程#xff08;高级#xff09;
1、类变量和类方法
#xff08;1#xff09; 概念
类变量#xff0c;也称为静态变量#xff0c;是指在类级别声明的变量。它们与特定类相关联#xff0c;而不是与类的实例#xff08;对象#xff09;相关联。每个类变量只有…面向对象编程高级
1、类变量和类方法
1 概念
类变量也称为静态变量是指在类级别声明的变量。它们与特定类相关联而不是与类的实例对象相关联。每个类变量只有一份副本它被类的所有实例共享。 static 变量保存在Class实例的尾部。而class对象确实存在堆中所以可以认为static放在堆中 理解
static变量是同一个类所有对象共享static类变量在类加载的时候就生成了
类方法静态方法是与类本身相关联的方法而不是与类的实例对象相关联。它们可以直接通过类名调用不需要实例化对象。当方法中不涉及到任何对象相关的成员就可以将方法设计成静态方法提高开发效率。 举例比如工具类里面的方法utilsMath类、Arrays类、Collections集合 2定义
类变量语法1、 访问修饰符 static 数据类型 变量名;(推荐)2、 static 访问修饰符 数据类型 变量名;类方法语法1、 访问修饰符 static 数据返回类型 方法名{};(推荐)2、 static 访问修饰符 数据返回类型 方法名{};3访问
类变量访问1、 类名.类变量名 (推荐) 静态变量的访问修饰符的访问权限和范围和普通变量是一样的。2、 对象名.类变量名类方法访问1、 类名.类方法名 (推荐) 静态变量的访问修饰符的访问权限和范围和普通变量是一样的。2、 对象名.类方法名 举例
类变量
public class StaticTest {public static void main(String[] args) {//类名.类变量名//类变量是随着类的加载而创建不用创建对象也可以访问System.out.println(A.name);A a new A();//通过对象名.类变量名也可以访问System.out.println(a.name);}
}class A{//类变量也需要遵循相关的访问权限public static String name 你好;//普通属性/普通成员变量/非静态属性/非静态成员变量private int num 10;
}类方法
public class Student {public static void main(String[] args) {//类.类方法进行调用Stu.Pay(100);Stu.Pay(200);Stu.Show();System.out.println(MyTools.calSum(10,30));}
}//开发自己的工具类可以将方法做成静态的方便调用
class MyTools{public static double calSum(double n1, double n2){return n1 n2;}
}class Stu{public static double totalFee 0;private String name;public Stu(String name) {this.name name;}//1、方法使用static修饰时该方法就为静态方法//2、静态方法只能访问静态变量public static void Pay(double fee){Stu.totalFee fee;}public static void Show(){System.out.println(总学费为totalFee);}
}4注意事项和细节 什么时候需要用类变量 需要某个类的所有对象都共享一个变量时就可以考虑使用类变量静态变量 类变量和实例变量普通变量的区别 类变量时类的所有对象共享实例变量是每个对象共享 实例变量不能通过 类名.类变量名进行访问 静态变量是类加载的时候就创建了所以不需要实例化对象也可以访问 类变量的声明周期是随着类的加载开始随着类消亡而销毁 静态方法类方法只能访问静态成员 类方法和普通方法都是随着类的加载而加载将结构信息存储在方法区类方法中无this参数普通方法中隐藏着this参数。普通方法主要不能直接通过类名.类方法进行调用 类方法中不允许使用和对象有关的关键字比如this和super普通方法可以
5类方法与普通方法的对比
特点普通方法实例方法类方法静态方法关联实例隶属于类的实例通过实例化对象调用不隶属于特定对象实例直接通过类名调用访问实例变量可以访问和操作实例变量和实例方法也可以访问静态方法、静态变量不能直接访问实例变量或实例方法只能访问静态方法和静态变量this、super关键字可以在方法中使用 this 关键字、super关键字不能在方法中使用 this 或 super 关键字动态绑定支持动态绑定根据对象类型执行方法不支持动态绑定根据类类型执行方法非静态上下文在对象实例上下文中执行在静态上下文中执行
2、理解main方法
public static void main(String[] args){}main方法是虚拟机调用的 java虚拟机需要调用类的main方法不同类、不同包所以该方法的访问权限必须是public java虚拟机在执行main方法的时候不用创建对象所以该方法是static 该方法接受String类型的数组参数该数组中保存执行java命令时传递给所运行的类的参数 java 执行的程序 参数1 参数2 参数3main方法中可以直接调用main所在类的静态方法和静态属性但是不能使用非静态方法和属性除非创建该类的实例对象之后才能通过这个对象去访问类的
IDEA如果给main函数传参 3、代码块
1概念
代码块是初始化块属于类中的成员类似于方法将逻辑语句封装在方法体重通过{}包围起来。但与方法不同没有方法名参数和返回值只有方法体 不需要对象或者类显示的调用而是加载类或创建对象时隐式的调用。
2语法
[修饰符]{代码
};修饰符可选要么不写要么就是static写了static的代码块叫静态代码块没有static修饰的叫普通代码块/非静态代码块最后面的分号可写可不写。里面的代码可以是任何的逻辑语句比如输入、输出、方法调用循环判断等等相当于另外一种形式的构造器对于构造器的补充机制可以做初始化的操作如果多个构造器里面都有重复的雨具可以抽取到初始化块当中提高代码的重用性。
3注意事项 静态代码块static作用是对类进行初始化随着类的加载而执行并且 只会执行一次如果是普通的代码块每创建一个对象就会执行。 类什么时候被加载【重要】 创建对象实例时new创建子类对象实例父类会被加载使用类的静态成员时静态属性、静态方法 普通的代码块在创建对象实例时会被隐式的调用。被创建一次就会被调用一次。如果只是使用类的静态成员时普通代码块并不会执行。 创建对象时一个类的调用顺序【重点和难点】 调用静态代码块和静态属性的位置多个则按顺序来调用普通代码块和普通属性多个按顺序来调用构造方法 举例 package JavaEE.chapter08.CodeBlock;public class CodeBlockDetail02 {public static void main(String args[]){A a new A();}
}class A{private int n2 getN2();private static int n1 getN1();{System.out.println(A的普通代码块);}static {System.out.println(A的静态代码块);}public static int getN1(){System.out.println(getn1被调用);return 100;}public int getN2(){System.out.println(A普通方法被调用);return 200;}public A(){System.out.println(无参构造器);}}/*输出
getn1被调用
A的静态代码块
A普通方法被调用
A的普通代码块
无参构造器
*/构造器的最前面隐含了super()和调用普通代码块静态相关的代码块属性初始化在类加载的时就执行完毕了因此是优先于构造器和普通代码块执行的。 举例 class A{public A(){ //构造器//隐藏的执行要求//(1)super();//(2)调用普通代码块System.out.println(无参构造器);}
}创建子类对象时静态代码块静态属性初始化普通代码块普通属性初始化构造方法调用顺序 父类的静态代码块和静态属性子类的静态代码和静态属性父类的普通代码块和普通属性父类的构造方法子类的普通代码块和普通属性子类的构造方法 个人总结 类加载父类-子类相关static代码执行构造器 super父类普通代码块构造方法 静态代码块只能调用静态成员普通方法可以调用任意成员。
4、单例设计模式
1设计模式
设计模式是在大量的实践中总结和理论化之后优选的代码结构编程风格以及解决问题的思考方式。
2单例设计模式介绍 单例设计模式就是在整个的软件系统中采取一定的方法保证某个类只能存在一个对象实例并且该类只提供一个取得其对象实例的方法 实现方式 饿汉式还没有用到对象可能对象已经创建好 构造器私有化类的内部构造对象向外暴露一个静态的公共方法返回对象 举例 class GirlFriend {private String name;//第一步将构造器私有化private GirlFriend(String name){this.name name;}//第二步在类的内部直接创建静态对象private static GirlFriend gf new GirlFriend(小红);//第三步提供一个公共的static方法返回gf对象public static GirlFriend getInstance(){return gf;}Overridepublic String toString() {return GirlFriend{ name name \ };}
}懒汉式只有当用户使用getInstance的时候才返回对象再次调用时返回是上次创建的cat对象 第一步构造器私有化第二步定义一个新的static静态对象第三步提供一个public的static方法可以返回一个对象 举例 //单例设计模式的懒汉式
class Cat{private String name;public static int n1 999;//第一步构造器私有化private Cat(String name) {System.out.println(类加载。。。。);this.name name;}//第二步定义一个新的static静态对象private static Cat cat;//第三步提供一个public的static方法可以返回一个Ca对象public static Cat getInstance(){//还没有对象就创建对象if(cat null){cat new Cat(小花喵);}return cat;}Overridepublic String toString() {return Cat{ name name \ };}
}3饿汉式和懒汉式对比
饿汉式是在类加载的时候就创建了对象实例而懒汉式是在使用时才创建饿汉式不存在线程安全问题懒汉式存在线程安全问题饿汉式存在浪费资源的可能懒汉式不存在这个问题javaSE中java.lang.Runtime是一个经典的单例模式
5、FINAL 关键字
final 是 Java 中的一个关键字它可以确保常量的值不会被修改。对于方法和类它可以确保方法实现或类结构不会被修改或继承改变这在某些情况下有助于代码的安全性和性能优化。
1final应用场景
对变量使用 final 当应用于变量时final 关键字表示该变量只能被赋值一次。一旦赋值后就不能再更改。这适用于基本数据类型和对象引用。例如final int x 10; 声明了一个只能被赋值一次的整数变量 x。 对方法使用 final 当应用于方法时final 表示该方法不能被子类重写覆盖。例如final void someMethod() { // do something } 定义了一个不能被子类重写的方法。 对类使用 final 当应用于类时final 表示该类不能被继承即它是最终的不能有子类。例如final class MyClass { // class definition } 声明了一个不能被继承的类。
2注意事项 final修饰的属性又叫做常量一般用用XX_XX来命名大写加下划线 final修饰的属性必须赋初值并且以后不能被修改赋值可以有以下三个地方可以进行 定义例如 public final double TAX_RATE 0.5;构造器中代码块中 如果final修饰的属性是静态的初始化的位置只能是 定义中静态代码块中 类不是final类但是含有final方法方法不能被重写但是可以被继承 举例 public class FinalDetail01 {public static void main(String[] args) {BB bb new BB();bb.cal();}
}
class AA{final public void cal(){System.out.println(CAL方法);}
}
class BB extends AA{}一般来说一个类已经是final类了没有必要再将方法修饰成final方法。因为已经无法被继承了 final不能修饰构造方法即构造方法 final和staic往往搭配使用效率更高不会导致类加载底层编译器做了优化处理 举例 class Demo{public final static int n1 16;static {System.out.println(这里是类加载不会被执行);}
}包装类IntegerDoubleFloatBoolean等都是finalString也是final类。
6、抽象类
1介绍
当父类的一些方法不能确定时可以用abstract关键字来修饰该方法这个方法就是抽象方法用abstract来修饰该类就是抽象类。抽象类通常用于当我们希望有一个通用的类定义但其中的某些方法在基类中并不具备实际的实现而是应该由具体的子类来实现。在框架和设计模式比较多
举例
//抽象类不能被实例化有抽象方法这个类必须声明为abstract
abstract class AA{//抽象方法没有方法体public abstract void eat();
}2注意事项 抽象类不能被实例化 抽象类可以没有抽象方法但是有抽象方法的类一定是抽象类。 举例 abstract class BB{public void cal(){System.out.println(抽象类可以没有抽象方法);}
}抽象类只能修饰类和方法不能修饰属性和其他的类型。 抽象类可以有任意成员 抽象类本质还是类比如非抽象方法、构造器、静态属性等。 举例 abstract class BB{//属性private String name;//构造器public BB() {}//普通方法public void cal(){System.out.println(抽象类可以没有抽象方法);}//抽象方法没有方法体abstract void hi();
}如果一个类继承了抽象类则它必须实现抽象类的所有抽象方法除非它自己也声明为abstract类 举例 abstract class E{public abstract void hi();public abstract void sorry();
}
//子类必须实现父类的所有抽象方法
class F extends E{public void hi(){System.out.println(hi);}public void sorry() {System.out.println(sorry);}
}抽象方法不能用private、final和static来修饰因为这些关键字是与重写相违背的。
3抽象类实践-模版设计模式
抽象类体现的是一种模版模式的设计抽象类作为多个子类的通用模板子类在抽象类的基础上进行扩展改造但子类总体会保留抽象类的行为模式。
可以解决的问题有
当功能内部一部分是确定的一部分是不确定的这时可以把不确定的部分暴露出去让子类去实现编写一个抽象父类父类提供多个子类的通用方法并把一个活多个方法留给子类实现这个就是模版设计模式。
举例
abstract class Template{public abstract void job();//一部分抽象一部分不抽象可以转变为一个模板提供给子类实现public void calculate(){long time System.currentTimeMillis();job();long nowtime System.currentTimeMillis();System.out.println(该任务执行时间为(nowtime-time));}
}class Cat extends Template{//子类只需要负责实现抽象部分即可public void job(){long sum 0;for (int i 0; i 8000000; i) {sum i*2;}}
}class Tiger extends Template{//子类只需要负责实现抽象部分即可public void job(){long sum 0;for (int i 0; i 8000000; i) {sum i;}}
}7、接口
1 基本介绍
接口就是给出一些没有实现的方法封装到一起到某个类需要使用的时候在根据具体情况把这些方法写出来
语法
interface 接口名{//属性//方法
}class 类名 implements 接口{//自己属性//自己方法//必须实现的接口的抽象方法
}
//Jdk7.0之前接口里面的所有方法都没有方法体
//Jdk8.0之后接口中可以有方法的具体实现默认方法、或者静态方法接口是更加抽象的抽象的类Jdk8.0之后接口类里面可以用静态方法默认方法可以有具体方法的实现。
举例
interface AInterface{public int n1 10;//抽象方法public void hi();//使用关键字default修饰之后可以实现具体的方法default void ok(){System.out.println(这里可以声明方法);}//使用static修饰之后也可以实现具体的方法static void you(){System.out.println(这里可以声明方法);}
}//需要实现接口类的所有抽象方法
class A implements AInterface{Overridepublic void hi() {System.out.println(实现接口类的抽象方法);}
}2注意事项 接口不能被实例化 接口中所有的方法都是public方法接口中的抽象方法可以不用abstract修饰 void aaa();
实际上等同于 public abstract void aaa();一个普通类实现接口就必须将该接口的所有方法都实现。而抽象类实现接口就可以不用实现接口的方法。 interface AInterface{//抽象方法public abstract void hi();
}//抽象类可以不用实现抽象方法
abstract class B implements AInterface{
}一个类可以实现多个接口 interface AI{}
interface BI{}
class BC implements AI, BI{}接口中的属性只能是final而且是public static final修饰符比如int a 1;实际上是 public static final int a 1必须初始化属性访问形式接口名.属性名 接口不能继承其他的类但是可以继承多个别的接口 interface AI{}
interface BI{}
interface BD extends AI,BI{}接口的修饰符只能是public或者是默认的 这里和普通的类一样
3接口对比继承
接口是对行为的抽象而继承是对类的抽象。 当子类继承了父类就自动拥有父类的功能。如果子类需要扩展功能可以通过实现接口的方式扩展。可以理解为接口是对单继承机制的一种补充。
继承的价值解决代码的复用性和可维护性is - a关系接口的价值设计好各种规范方法让这些类去实现这些诶方法更加的灵活。like -a 关系接口在一定程度上可以实现代码的解耦接口规范性动态绑定
4 接口多态 接口的多态 多态数组 以上两种举例 public class InterfacePolyParameter {public static void main(String[] args) {//接口的多态//接口类型的变量 if01可以指向实现了IF接口的类的对象实例IF if01 new Monster();if01 new Car();//多态数组IF[] if02 new IF[2];if02[0] new Monster();if02[1] new Car();}
}interface IF{}
class Monster implements IF {}
class Car implements IF{}接口多态传递
public class InterfacePoly {public static void main(String[] args) {//接口类型变量可以指向实现该接口的类的对象实例IG ig new Teacher();//IG继承了IH接口Teacher实现了IG接口相当于Teacher实现了IH接口这就是接口的多态传递现象IH ih new Teacher();}
}
interface IH{}
interface IG extends IH{}
class Teacher implements IG{}8、内部类【难点和重点】
1基本介绍
一个类的内部有完成的嵌套了另外一个类的结构。被嵌套的类称为内部类inner class嵌套其他类的类称为外部类outer class。是类的第五大成员属性、方法、构造器、代码块、内部类内部类的最大特点就是可以直接访问私有属性并且可以体现类与类之间的包含关系。在很多源码当中都有大量内部类。
举例
//类的五大成员
class Outer{//外部类//属性private int n1 100;//构造器public Outer(int n1) {this.n1 n1;}//方法public void m1(){System.out.println(方法);}//代码块{System.out.println(代码块...);}//内部类class Inner{//内部类在Outer类的内部}
}内部类的种类
在局部位置方法/代码块 局部内部类有类名匿名内部类没有类名重点 成员位置 成员内部类没有static修饰静态内部类有static修饰
基本语法
class Outer{//外部类class Inner{//内部类}
}2局部内部类
局部内部类是定义在外部类的局部位置比如方法或者代码块中并且有类名
可以直接访问外部类的所有成员包含私有成员不能添加访问修饰符因为这是一个局部变量可以使用final局部变量可以使用final作用域仅仅在定义它的方法或者代码块中局部内部类—访问----外部类的成员[访问方式直接访问]外部类—访问—局部内部类的成员[访问方式创建对象后再访问必须在作用域内]外部其他类—不能访问----局部内部类如果外部类与局部内部类的成员重名时遵循就近访问原则如果想访问外部类的成员可以使用[外部类名.this.成员]去访问
举例
class Outer02{//外部类private int n1 10;private void m2(){}//私有方法public void m1(){//方法//1、局部内部类是定义在外部类的局部位置通常实在方法里面//3、不能添加访问修饰符但是可以使用final修饰不能被继承//4、作用域仅仅在方法或代码块中class Inner02{ //局部内部类本质仍为一个类private int n1 800;public void f1(){//2、可以直接访问外部类的所有成员包含私有的//5、局部内部类可以直接访问外部类的成员比如n1m2()//7、如果外部类和局部内部类的成员重名时默认遵循就近原则如果想访问外部类的成员可以使用 外部类名.this.成员去访问//Outer02.this 的本质就是外部类的对象哪个对象调用了m1Outer02.this就是哪个对象System.out.println(内部类n1 n1);System.out.println(外部类的n1 Outer02.this.n1);m2();}}//6、外部类在方法中可以创建Inner02对象然后调用方法即可Inner02 inner02 new Inner02();inner02.f1();}
}注意事项
局部内部类定义在方法中/代码块中作用域在方法体或者代码块中本质仍然是一个类
3匿名内部类重要
匿名内部类是一个没有类名的内部类。如果一个内部类的对象在一个地方只需要用一次那么我们可以使用匿名内部类它可以简化代码使得代码更易于阅读。匿名内部类在编译的时候由系统自动用其父类名加$1、$2这样的方式来命名。
匿名内部类定义在外部类的局部位置比如方法中并且没有类名
基本语法
new 类或接口(参数列表){类体
};
//参数列表会传给类的构造器举例
class Outer04{//外部类private int n1 10;//属性public void method(){//方法//基于接口的匿名内部类//1、需要A接口并创建对象//2、传统方法是写一个类实现接口并创建对象//3、只需要使用一次后面不需要再使用//4、使用匿名内部类简化开发//5、匿名内部类tiger的运行类型为 Outer04$1编译类型是A//6、匿名内部类的底层实现/*class Outer04$ implement A{public void cry() {System.out.println(老虎在叫);}}*///7、jdk在底层创建匿名内部类Outer04$1,立马就创建了Outer04$01实例并且把地址返回//8、匿名内部类使用一次就不再使用A tiger new Tiger(){public void cry() {System.out.println(老虎在叫);}};tiger.cry();
// A tiger new Tiger();
// tiger.cry();}
}interface A{//接口public void cry();
}class Tiger implements A{Overridepublic void cry() {System.out.println(老虎在叫);}
}注意事项与局部内部类类似
语法比较不一样既有定义类的特征也有创建对象的特征。可以直接访问外部类的所有成员包含私有成员不能添加访问修饰符因为这是一个局部变量可以使用final局部变量可以使用final作用域仅仅在定义它的方法或者代码块中外部其他类—不能访问----局部内部类如果外部类与局部内部类的成员重名时遵循就近访问原则如果想访问外部类的成员可以使用[外部类名.this.成员]去访问
实践
public class AnonymousClassPractice {public static void main(String[] args) {//1、将匿名内部类直接当做实参传入函数当中f1(new Fot() {//软编码模式Overridepublic void show() {System.out.println(匿名内部类重写show方法);}});//正常实现,比较麻烦Example example new Example();f1(example);}public static void f1(Fot fot){fot.show();}
}interface Fot{void show();
}//硬编码模式
class Example implements Fot{Overridepublic void show() {System.out.println(普通类重写show方法);}
}4成员内部类
成员内部类是创建在外部类的成员位置没有static修饰
注意事项
可以直接访问外部类的所有成员包含私有成员可以添加任意的修饰符public、protected、private、默认可以认为这个类就是一个成员作用域是和其他类的成员一样是整个类体成员内部类-----访问-----外部类成员比如属性【访问方式直接访问】外部类------访问------成员内部类【访问方式创建对象再访问】外部其他类-----访问-----成员内部类【两种方式外部类名.new 内部类名或者外部类名创建一个方法返回内部类】如果外部类和内部类的成员重名时内部类访问遵循就近原则如果想访问外部类的成员可以使用外部类名.this.成员去访问
举例
public class MemberInnerClass {public static void main(String[] args) {Outer08 outer08 new Outer08();outer08.t1();//外部其他类访问成员内部类的两种种方式//第一种方式把内部类当做外部类的一个成员来使用Outer08.Inner08 inner08 outer08.new Inner08();inner08.say();//第二种方式在Outer里面创建一个方法这个方法返回一个内部类地址Outer08.Inner08 inner081 outer08.getInner08Instance();inner081.say();}
}class Outer08{private int n1 10;public String name 张三;//1、内部类是定义在外部类的成员位置//2、可以用public、private、protected修饰//3、作用域在整个类体class Inner08{//成员内部类public void say(){//4、可以访问外部类的所有成员包含私有的System.out.println(n1 n1 name name);}}public void t1(){//5、外部类使用内部类创建对象使用他的成员即可Inner08 inner08 new Inner08();inner08.say();}public Inner08 getInner08Instance(){return new Inner08();}
}5静态内部类
静态内部类是定义在外部类的成员位置并且有static修饰与成员内部类基本没有区别
注意事项
可以直接访问外部类的所有成员包含私有成员可以添加任意的修饰符public、protected、private、默认可以认为这个类就是一个成员作用域是和其他类的成员一样是整个类体成员内部类-----访问-----外部类成员比如属性【访问方式直接访问】外部类------访问------成员内部类【访问方式创建对象再访问】外部其他类-----访问-----成员内部类【两种方式外部类名.new 内部类名或者外部类名创建一个方法返回内部类】如果外部类和内部类的成员重名时内部类访问遵循就近原则如果想访问外部类的成员可以使用外部类名.成员去访问 【不需要加this】