面向对象——static(静态)&Math类&自定义工具类&代码块
static(静态)关键字
-
static是一个修饰符,用于修饰成员(成员变量 、成员方法) static的特点
–随着类的加载而加载
–优先于对象存在
–被类的所有对象共享
–可以被类名调用
案例:
package com.demo01; /* * static:是一个关键字,用于修饰成员变量和成员方法 * static的特点: * 被所有的对象所共享 * 可以使用类名调用 * 静态的加载优先于对象 * 随着类的加载而加载 * */ public class StaticDemo { public static void main(String[] args) { Person.graduateFrom = "湖南大学"; Person p = new Person(); p.name = "段誉"; p.age = 18; //p.graduateFrom = "湖南大学"; p.speak(); Person p2 = new Person(); p2.name = "萧峰"; p2.age = 20; //p2.graduateFrom = "湖南大学"; p2.speak(); Person.think(); } } class Person { String name; int age; static String graduateFrom;//毕业院校 public void speak() { System.out.println(name + "---" + graduateFrom); } public static void think() { System.out.println("思考"); } }
分析:先Person.graduateFrom = "湖南大学";才创建一个类对象,静态得成员变量应该用一种静态得方法来访问,用Person 来访问,不应该用p.得方式来访问。
static的注意事项
静态方法:
* 1、可以调用静态的成员变量
* 2、可以调用静态的成员方法
* 3、不可以调用非静态成员变量
* 4、不可以调用非静态成员方法
* 静态方法只能调用静态的成员
非静态方法:
* 1、可以调用静态的成员变量
* 2、可以调用静态的成员方法
* 3、可以调用非静态的成员变量
* 4、可以调用非静态的成员方法
* 静态的方法中是否this这个对象?没有的
分析:静态方法是属于类的,而非静态的成员,不管是成员变量,还是成员方法,他是属于对象的,静态方法在调用类的时候已经初始化好了,静态如果可以调用非静态成员时,会发现他是不属于类的,是属于对象的,现在还没有对象呢,那怎么办呢?所以相互矛盾,所以静态是无法调用非静态的,反过来,非静态是可以调用静态成员变量。我们在待用静态时,是已经声明了对象,才调用的。
package com.demo01; /* * static的注意事项: * 静态方法: * 1、可以调用静态的成员变量 * 2、可以调用静态的成员方法 * 3、不可以调用非静态成员变量 * 4、不可以调用非静态成员方法 * 静态方法只能调用静态的成员 * 非静态方法: * 1、可以调用静态的成员变量 * 2、可以调用静态的成员方法 * 3、可以调用非静态的成员变量 * 4、可以调用非静态的成员方法 * * 静态的方法中是否this这个对象?没有的 * * */ public class StaticDemo2 { public static void main(String[] args) { Student.graduateFrom = "湖南大学";//1、可以调用静态的成员变量 //Student.study(); Student s = new Student(); s.eat(); } } class Student { String name; int age; // static String graduateFrom;//毕业院校 public static void study() { //System.out.println(graduateFrom); sleep();//可以调用静态的成员方法 //System.out.println(name);//不可以调用非静态成员变量 //eat();//不可以调用非静态成员变量,这样是错误得 } public static void sleep() { System.out.println("sleep"); } public void eat() { System.out.println("eat"); System.out.println(graduateFrom); sleep(); } }
static的优点和缺点
-
static的优点
–对对象的共享数据提供单独空间的存储,节省空间,没有必要每一个对象都存储一份
–可以直接被类名调用,不用在堆内存创建对象
-
static的弊端
–访问出现局限性。(静态虽好,但只能访问静态)
应用场景
-
Math 类包含用于执行基本数学运算的方法。数学操作常用的类。 Math类的使用
–没有构造方法,我们如何使用呢?
-
Math类要掌握的功能
–字段:PI
–方法:abs ,max,min ,pow,ceil,floor,round,random
package com.demo02; public class MathDemo { public static void main(String[] args) { //Math:包含了一些基本的数学运算方法 //static double PI System.out.println(Math.PI); // //static double abs(double a) :返回绝对值 System.out.println(Math.abs(15.67)); System.out.println(Math.abs(-0.10)); //static double ceil(double a) 天花板 向上取整 System.out.println(Math.ceil(-2.1)); System.out.println(Math.ceil(1.6)); //static double floor(double a) 地板 向下取整 System.out.println(Math.floor(1.2)); System.out.println(Math.floor(-1.6)); //static long round(double a) :四舍五入 System.out.println(Math.round(-1.2)); System.out.println(Math.round(1.6)); //static double max(double a, double b) System.out.println(Math.max(3, 4)); //static double pow(double a, double b) :返回第一个参数的第二个参数次幂 System.out.println(Math.pow(3, 4)); //static double random() :返回一个随机数,大于零且小于一 System.out.println(Math.random()); } }
自定义工具类
案例:
package com.demo03; /** * 数组工具类 * @author (无限嚣张(菜菜)) * */ public class MyArrays { private MyArrays() {} /* * 返回数组中最大的元素 * */ public static int getMax(int[] arr) { if(arr==null||arr.length==0) { return 0; } int max = arr[0];//参照物 //遍历数组 for(int x = 1;x < arr.length;x++) { if(arr[x] > max) { max = arr[x];//替换参照物 } } return max; } /* * 返回数组中指定参数的索引 * */ public static int getIndex(int[] arr,int a) { //遍历数组 for(int x = 0;x < arr.length;x++) { if(arr[x] == a) { return x; } } return -1;//如果查不到指定的参数,则返回-1 } }
package com.demo03; public class MyArraysDemo { public static void main(String[] args) { //MyArrays m = new MyArrays(); int[] arr = {3,5,8,10,1}; int max = MyArrays.getMax(arr); System.out.println(max); int index = MyArrays.getIndex(arr, 8); System.out.println(index); } }
代码块
-
在Java中,使用{}括起来的代码被称为代码块 代码块分类
–局部代码块——存在于方法中,控制变量的生命周期(作用域),用完销毁
–构造代码块——提取构造方法中的共性,每次创建对象都会执行,并且在构造方法执行之前执行
–静态代码块——随着类的加载而加载,只加载一次,加载类时需要做的一些初始化,比如加载驱动
–同步代码块(多线程)
package com.demo04; public class BlockDemo { public static void main(String[] args) { //局部代码块:存在于方法中,控制变量的生命周期(作用域),用完销毁 { for(int x = 0;x < 10;x++) { System.out.println("我爱Java"); } int num = 10; } //System.out.println(num); Teacher t = new Teacher(); Teacher t2 = new Teacher("王老师",18); } } class Teacher { String name; int age; //构造代码块:提取构造方法中的共性,每次创建对象都会执行,并且在构造方法执行之前执行 { for(int x = 0;x < 10;x++) { System.out.println("我爱Java"); } System.out.println("我爱Java"); } //静态代码块:随着类的加载而加载,只加载一次,加载类时需要做的一些初始化,比如加载驱动 static { System.out.println("我爱Java"); } public Teacher() { System.out.println("我是无参空构造"); } public Teacher(String name,int age) { System.out.println("我是有参构造"); this.name = name; this.age = age; } }
分析:我们首先new一个无参的对象,进去以后执行局部代码块,输出10词我爱Java,num=10,运行完以后num就被删除了,我们new 一个teacher对象,首先执行的静态代码块,执行完以后,就执行构造代码块,执行完构造代码块才执行构造方法。