Java面向对象与关键字

面向对象思想

  • 面向过程:面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然后由这些功能方法相互调用,完成需求。例如杨辉三角型,打印图形、输入元素每一大步如何做都需要一步一步写出来;
  • 面向对象:封装过程,按照需求调用功能;

面向对象的理解:

  • 把需求步骤和功能再进行封装,封装时根据不同的功能,进行不同的封装,功能类似的封装在一起。
    这样结构就清晰了很多。用的时候,找到对应的类就可以了。这就是面向对象的思想。
  • 面对对象的程序是由类实例化对象组成的, 每个对象包含对用户公开的特定功能部分和隐藏的实现部分。程序中的很多对象来自标准库,还有一些是自定义的。
  • 类体现封装的思想,封装成员属性和成员功能,例如创造一个机器人类,它需要皮肤(成员)、设置皮肤的颜色(成员属性),会运动(功能);

类与对象

描述现实世界事物:

  • 学生这个事物:
    属性: 姓名 , 年龄 , 性别 …
    功能: 学习 , 吃饭 , 睡觉 …

学习编程语言,就是为了模拟现实中的事物,我们学习的Java语言最基本单位是类,所以,我们就应该把事物用一个类来体现。

  • 现实中的事物和类的对应关系:

      事物				       类
      属性	----------------- 成员变量
      行为	----------------- 成员方法
    
  • 再举例:手机这个类就有属性(颜色、大小)和功能(玩游戏),手机中的成员可以为屏幕、键盘,屏幕的颜色就是成员属性。

定义类:就是定义类的成员(成员变量和成员方法)
a:成员变量 和以前定义变量是一样的,只不过位置发生了改变。在类中,方法外。
b:成员方法 和以前定义方法是一样的,只不过把static去掉,后面在详细讲解static的作用。

类和对象的概念

a:类:是一组相关的属性和行为的集合
b:对象:是该类事物的具体体现
c:举例:
	类	学生
	对象	班长就是一个对象
  • 封装是与对象有关的一个重要概念。从形式上看,封装就是将数据和行为组合在一个包中, 并对对象的使用者隐藏了数据的实现方式。实现封装的关键在于绝对不能让类中的方法直接地访问其他类的实例域。程序仅通过对象的方法与对象数据进行交互。封装给对象赋予了“ 黑盒” 特征, 这是提高重用性和可靠性的关键。 这意味着一个类可以全面地改变存储数据的方式,只要仍旧使用同样的方法操作数据, 其他对象就不会知道或介意所发生的变化。OOP 的另一个原则会让用户自定义 Java 类变得轻而易举,在 Java 中, 所有的类都源自于一个"神通广大的超类"Object。

类的使用

  • 创建对象格式:
    类名 对象名 = new 类名();

  • 使用成员变量格式:
    对象名.变量名

  • 使用成员方法格式:
    对象名.方法名(...)

  • main这个类方法是程序运行的入口,用来调用别的类,因此调用类是在程序的main方法下执行的
    方法区先加载 Test.class文件,然后读取main方法来执行程序,调用其他的类等等。

  • 使用类时,在一个java文件夹(package)中写两个类:一个基本的自定义类,一个测试类。测试类用来调用自定义的类,在main方法下执行。

  • 多个类可以并列定义到一个java文件中,但是public只能加给带有main方法,作为入口的类。
    建议一个类就是一个java文件
    举例:自定义一个手机类如下:

public class Phone {
      // 定义成员变量
    String name="小米";
    String color="白色";
    double price=799;
	
	//定义成员方法
    public void call(String name){
        System.out.println("给"+name+"打电话");
    }

    public void sendMsg(String name,String content) {
        System.out.println("给"+name+"发了短信:"+content);
    }
}

测试类如下:

public class MyTest {
    public static void main(String[] args) {
        
        //创建Phone类的对象
        Phone phone = new Phone();
        
        //获取成员变量的值
        String name = phone.name;
        String color = phone.color;
        double price = phone.price;
        System.out.println(name);
        System.out.println(color);
        System.out.println(price);
        // 打印对象地址值
        System.out.println(phone);
		
		//调用成员方法
        phone.call("王祖贤");
        phone.sendMsg("林青霞","很想你");
        }
  }

创建一个对象的内存图解:
在这里插入图片描述
创建一个对象分析: Student s = new Student();
内存步骤如下:

(1):加载Student.class文件进内存
(2):在栈内存为s开辟空间
(3):在堆内存为学生对象开辟空间
(4):对学生对象的成员变量进行默认初始化
(5):对学生对象的成员变量进行显示初始化
(6):通过构造方法对学生对象的成员变量赋值
(7):学生对象初始化完毕,把对象地址赋值给s变量

创建多个对象分析:

  • 一个对象内存图:栈内程序调用什么类,类的字节码文件就进方法区,调用main方法,main方法进栈执行程序,堆中实例化对象,将类的成员变量拷贝一份进行默认初始化,如果类方法中定义了值会迅速覆盖默认值,返回地址值给栈中对象名。方法在方法区中,栈中加载类方法与自定义方法执行,执行完后弹栈。
  • 2个对象的内存图:每new一次会开辟新的内存空间,将类的成员变量拷贝一份进行默认初始化,如果类方法中定义了值会迅速覆盖默认值,返回地址值给栈中对象名。接下来栈中按照程序执行。
  • 3个对象的内存图:如果第三个对象为Person p1=p;表示将p的地址值赋给p1,p1与p指向同一个地址,两个对象的属性值与方法均相等。没有new不会在堆中开辟新的内存空间

局部变量和成员变量的区别

A:在类中的位置不同
成员变量:在类中方法外,new对象时在堆内才会初始化类的成员变量,因此成员变量属于对象。
局部变量:在方法定义内部中或者方法声明(形参)上,属于方法。
B:在内存中的位置不同
成员变量:创建对象,在堆内拷贝成员变量并赋默认值,因此在堆内存储
局部变量:方法加载进栈,在栈内存储
C:生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
D:初始化值不同
成员变量:有默认初始化值,创建对象时在堆内拷贝成员变量并赋默认值
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。

注意事项:

  • 局部变量名称可以和成员变量名称同名时,在方法中使用的时候,采用的是就近原则;
    先在方法内部局部范围找变量;没有找到去成员范围找,找到就使用。没有找到就报错。

举例:

自定义一个类

//定义一个人的类 没有static
public class Person {
    //成员变量,对象属性
    int age;
    String name="scq";
    // 类方法
    public void age() {
        //age()没有传参,此age为成员范围的对象属性age变量,重新修改成员变量
        age=40;
        System.out.println(age);
    }

    public void show(int age) {
       //局部范围没有定义name的值,去成员范围找
        System.out.println(name); //scq
        System.out.println(age); //打印传入的参数age
        name="就近原则";
        System.out.println(name);//就近原则

        //age是局部变量,show调用完释放age
        age=100;//修改局部变量age
        System.out.println(age);//100

    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        Person p=new Person();
        p.age=3;
        System.out.println(p.age);//3
        p.age();//40 调用方法,修改成员变量p.age值
        //show方法中修改了局部变量age,与外部成员变量p.age无关
        System.out.println(p.age);//40

        //show的型参为age,与main方法的age无关
        p.show(20); //scq
                    //就近原则
                    // 20
        //show方法中修改了局部变量age,与外部成员变量p.age无关
        System.out.println(p.age);//40
    }
}

方法的形式参数是类名时如何调用

  • Java中参数传递问题
    形式参数
    1. 基本类型:属于值传递,形式参数的改变不改变实际参数
    2. 引用类型:属于引用传递,传递的是地址值,形式参数的改变直接改变实际参数
  • 方法的参数是类名
    如果你看到了一个方法的形式参数是一个类 类型(引用类型),这里其实需要的是该类的对象。就是将该类的对象地址值传入方法,当方法内部修改该对象的成员变量就是直接修改。

举例:
自定义一个类

public class Student{
    //student类对象的属性num初始化为20
    int num=20;
    }

测试类:


public class Test {
    public static void main(String[] args) {


        // 成员变量num
        int num=10;
        Student student=new Student();

        //形参为类的类型时,传递该类的对象。类是引用数据类型,传递地址值,形参改变影响实参。
        // test方法用来修改对象属性值。
        test(student,num);
        System.out.println(student.num);//30
//test中的局部变量num和成员变量num同名时:test内部的局部变量num在test方法调用完就是释放
//基本数据类型作为参数传递时传递值,局部变量num的改变不影响成员变量num
        System.out.println(num);//10
    }

    //定义一个test方法修改对象属性			//局部变量num
    public static void test(Student student,int num) {
        num+=20;
        //形参为对象,传入地址值,对student的num值重新赋值会直接修改student的num值
        student.num=num;
    }
}

图解:
在这里插入图片描述

匿名对象的概述和应用

匿名对象:

  • 就是没有名字的对象;
  • 表示堆内新建的对象没有把地址值赋给引用;
  • 如果当做实参传入自定义方法,传入的是匿名对象的地址值

创建对象格式:类名 对象名 = new 类名();
创建匿名对象的格式:new 类名(); 没有东西接收这个对象。因此堆内新建的对象也无法把地址值给引用。

匿名对象的应用:

  • 因为每new一次都是一个新的对象,所以调用方法,仅仅只调用一次的时候使用匿名对象。
  • 匿名对象可以作为实际参数传递

举例:
自定义一个类

public class Dog{
    int num=100;
    
    public void eat() {
        System.out.println("eating");
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        //new Dog()可以直接调属性方法和类方法
        System.out.println(new Dog().num);

        //两个匿名对象各调用了一次,每new一次就是一个新的内存空间,地址值不同。
        //因此  只调用方法一次的时候,就可以使用匿名对象来调用。
        // 如果要使用匿名对象的属性只能使用一次:使用方法为:new Dog().num
        new Dog().eat();
        new Dog().eat();
        //如果要一次修改匿名对象的属性值,方法如下:
        new Dog().num=10;

        //同一个对象 调用了eat()方法两次
        Dog dog=new Dog();
        dog.eat();
        dog.eat();

//匿名对象 作为参数传入方法
// 由于每new一次就是一个新的对象。当做实参传入自定义方法,传入的是匿名对象的地址值,并且修改了这个地址值内所对应对象的num的属性值,然后test方法执行结束,弹栈。
        test(new Dog(),20);//new Dog()开辟内存空间后,传入匿名对象的地址值

//Dog对象自身属性num初始值为100,test将num重新赋值 ,因为对象为引用数据类型,作为参数传递传入地址值,形参会改变实参。因此dog.num会重新赋值为30
        test(dog,30);
        System.out.println(dog.num);//30
//打印一个新的匿名对象 的属性值num ,没有赋值改变,因此为初始值100
        System.out.println(new Dog().num);
    }

    //定义一个传入对象修改对象属性的test方法
    public static void test(Dog dog,int num) {
        dog.num=num;
    }
}

图解:
在这里插入图片描述

private关键字的概述和特点

我们采用对象名.成员变量这种方式可以给成员变量设置值,但有时候类里面的成员变量需要有一些限制(如果用户输入年龄为230),如何屏蔽这种设置?

  1. 由于主方法内实例化对象后对成员变量直接赋值、直接操作成员方法不安全,因此给出权限修饰符;
  2. 我们可以使用关键字private,private是一个权限修饰符,可以修饰成员变量和成员方法,不可以修饰类。被修饰的成员只能在本类当中被访问。出了自定义类的范围,主方法(外界)无法访问到成员变量,也无法赋值,例如主方法内: phone.color="black";
  3. 外界可以通过对象调用类方法来赋值和获取加了private的成员变量,而类方法中加入一定条件外界才可以成功为成员变量赋值。更加安全。
  4. 私有变量,不可以在方法中当做形参传入,在方法中当做形参传入就是在对象调用时要传入的参数,此时表示对象可以访问这些私有变量,那么私有变量就毫无意义。
  •  

测试类:

public class mainmain {
    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle(3,2);
        rectangle.getLength();
        rectangle.getArea();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 权限修饰符
    范围:public > protected> 缺省的 (不写权限修饰符)> private
  1. 类可以用public 和 缺省来修饰,成员变量和成员方法都可以权限修饰符被修饰,类如果想被不同包下调到 不能缺省要加上public,不同包下只有public修饰的方法和成员变量可以访问;
  2. public范围最大,在任何地方都可以访问到。可以修饰类、成员变量、成员方法;

this关键字的概述和应用

当局部变量和成员变量名字相同的时候,如果我们不使用this关键字,局部变量会在自己的作用域内根据就近原则屏蔽了成员变量;也就是说当调用set方法时,形参名称与成员变量重名,按照就近原则无法找到成员变量,而为了区分成员变量和局部变量,使用this来区分

  • this关键字代表当前类的对象地址值,谁调用这个成员方法,那么该方法的内部的this就代表谁。使用this.变量名就可以在成员方法内部屏蔽局部变量找到成员方法外部的成员变量。
  • this的作用:解决局部变量隐藏成员变量

举例:
自定义一个类

public class Phone {
    int name; //缺省
    private String color;
    private double money;
    public void show(){
        //没有设置属性值之前,在实例化对象的时候堆会初始化默认值money为0.0,color为null
        System.out.println(money);
        System.out.println(color);
    }

   //提供public(类内部和外界都可以访问)的set/get方法,让外界通过调用方法给成员变量设置值和获取成员变量值。
    public void setMoney(double money) {
        if (money>=1000)
        this.money = money;
    }
    public double getMoney(){
//只有对象才能调用属性,某个对象调用这个成员方法,传入这个对象给this来调用这个对象的属性money
//下面不在成员变量money中加入this是因为此函数没有与成员变量相同的局部变量,因此按照就近原则可以找到方法外部的成员变量money,不需要加this区分。此时money前面有默认的this。
        return money;//就是 return this.money
    }

    public void setColor(String color){
 //按照就近原则,左边的color找传入的形参变量color,右边的color为传入值形参color,因此为自己赋值给自己。并没有将形参color给成员变量color赋值
        color=color;
 //this:类实例化对象的地址值,哪个对象调用这个方法,方法中的this就代表这个对象。 
 //通过对象.属性 , 找到成员变量实现为成员变量赋值
        this.color=color;

    }
    public String getColor() {
        this.call();  //call()为私有方法,外界无法调用,但是类内部可以调用
        return color; //此处省略了this.color直接用color,没有局部变量与成员变量重名,因此不影响,不需要用this来区分。
    }

    //私有方法,外界无法调用,但是类内部可以调用
    private void call(){
        System.out.println("call");
    }  
}

测试类:

Phone phone=new Phone();
 //没有设置属性值之前,在实例化对象的时候堆会创建内存空间拷贝类的成员变量并初始化默认值,money为0.0,color为null
 phone.show();// 0.0 null
 phone.setMoney(500);
 double money= phone.getMoney();
 System.out.println(money);//0.0
 phone.setColor("red");
 //对于有返回值的方法可以直接打印
 System.out.println(phone.getColor());//call  red

构造方法

构造方法概述:

  1. 在创建对象同时,构造方法会运行,以便将实例域初始化为所希望的状态;
  2. 构造方法与其他的方法有一个重要的不同:构造器总是伴随着 new 操作符的执行被调用;
  3. 每个类都有一个默认的无参的构造方法,但是如果你定义了有参的构造方法,这个无参的构造方法就不见了,如果你需要这个无参的构造方法,你需要自己手动添加;
  4. 不写构造方法默认带有空参构造。
  5. 构造方法可以重载,可以同时在类中写有参与无参的构造方法,因此每个类可以有一个以上的构造方法
  6. 构造方法可以有 0 个、1 个或多个参数

构造方法作用:

  • 有了构造方法才可以对类进行实例化。
  • 创建对象 , 可以通过有参构造方法来为成员变量赋值,无需set方法,更加方便。

构造方法格式:

  • :方法名与类名相同
  • :没有返回值类型,连void都没有
  • :没有具体的返回值
//使用关键字new 来调用构造方法实例化对象
 Student student = new Student();

一个标准的定义类的要求:
私有化成员变量,提供get set方法,写空参和有参的构造方法

举例:
定义一个标准的类

public class Student {
    private String name;
    private int age;

//重载构造方法,定义有参与无参的构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

测试这个类:

public class mainmain {
    public static void main(String[] args) {
        //借助空参构造方法创建对象,调用set方法给成员变量赋值
        Student student1 = new Student();
        student1.setAge(20);
        System.out.println(student1.getAge());//20
        
        //借助有参构造方法创建对象,同时给对象的成员变量赋值,常用比较方便
        Student student2 = new Student("scq", 22);
        System.out.println(student2.getAge());//22
        System.out.println(student2.getName());//scq
    }
}

static关键字

一、 static的引入
如果同一个类下多个对象有相同的属性值,例如三个都属于中国的人,为了让多个对象共享国籍这个属性,而自定义初始值也是每个对象都在内存中有存储一份,此值不是共享;共享是内存中只有一份,大家共享,如果想要让一个类的所有对象共享一个成员变量引入static

那么什么时候使用静态?
如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。举例:咱们班级的学生应该共用同一个班级编号。

自定义一个Person类,定义一个静态变量并赋值,那么这个类下的所有对象都会共享这个变量值

public class Person {
    public String name;
    //static 静态的,可以修饰成员变量和成员方法,此处修饰成员变量,
    // 此变量就为一个共享变量,会被这个类的所有对象,所共享。
    public static String country = "中国";
}

测试这个类,查看这个类下的对象共享情况

public class MyTest {
    public static void main(String[] args) {
        //静态的变量,通过类名直接调用,不需要new对象。
        Person.country="美国";//将静态变量country设置为美国
        Person p1 = new Person();
        p1.name = "张三";
		
		Person p2 = new Person();
        p2.name = "李四";
        System.out.println(p1.country);
        System.out.println(p2.country);

/*
* 输出结果:
* 美国
* 美国
 */

static的内存图解
在这里插入图片描述
分析:

  • Mytest类文件进入方法区,方法区在加载字节码文件的时候将区域分为静态区(被static修饰,如main())和非静态区,共享变量任何对象都可以设置,它们一被设置就会覆盖缺省的值;main方法位于静态区,栈中读取main方法中对Person类进行实例化对象,方法区内开辟空间读取Person类文件并分区,静态区初始化静态属性country并赋默认值,并用中国迅速覆盖默认值null;非静态区中加载非静态变量name
  • 在new对象时非静态成员在堆中拷贝一份并初始化赋默认值,随后被指定值覆盖掉;因此static所修饰的成员是在创建对象前(new 对象前)存在于方法区中;

注意:

  • 静态成员在类加载进内存方法区时会初始化并赋默认值,因此被静态修饰的成员属于类。当栈中遇到修改静态属性的代码时,方法区中的静态属性值就被覆盖从而影响所有对象的静态属性值;
  • 之后创建对象时非静态成员在堆中拷贝一份并初始化赋默认值,即静态修饰成员随着类加载而加载,在实例变量与实例方法之前存在,而实例变量与实例方法在new对象后才存在

二、 static关键字的特点

  • 共享性: static修饰成员变量和成员方法,修饰成员变量,此变量变为一个共享变量,会被所有对象共享。所有对象的这个属性值都相同。 成员变量本身属于对象,使用状态修饰符关键字static之后就使得成员变量/成员方法属于类,所有该类的对象都可以共享,只要有一个对象操作改变它,他就会发生改变;
  • 类成员:因为静态变量随着类的加载而加载属于类,可以通过类名调用,格式为类名.属性名 类名.方法名(),其实它本身也可以通过对象名调用。推荐使用类名调用。静态修饰的内容一般我们称其为类成员;
  • 静态只能访问静态。静态修饰成员随着类加载而加载,在实例变量与实例方法之前存在,而实例变量与实例方法在new对象后才存在,因此静态方法中不能调用非静态方法与非静态成员,静态方法只能访问静态修饰的成员(方法、变量),先有的(静态)访问不到后来(实例)才有的。,而非静态方法可以访问静态与非静态成员。后有的可以访问先有的;
  • 静态方法中是没有this关键字的。静态是随着类的加载而加载,this是随着对象的创建而存在。前者早于后者出现,因此静态方法里面不能有关键字this的出现,静态成员比对象先存在;而非静态方法中对于非静态方法的调用是省略了this

举例理解:自定义一个学生类

public class Student {
    //成员变量,实例变量
    private String name;
    //static 所修饰的变量,为一个共享变量,可以被该类的所有对象所共享。
    public static int num = 200;

//静态方法只能访问静态成员变量和成员方法
    public static void test() {
        System.out.println("这是一个静态的方法");
        // hehe(); 非静态方法报错 调用不到
        //System.out.println(name); name为非静态成员报错 调用不到
        System.out.println(num);
    }

    //非静态方法,成员方法 实例方法
    //非静态方法中,既可以非静态的成员,也可以访问静态成员。
    public void hehe() {
        System.out.println("这是一个普通的实例方法");
        System.out.println(name);
        System.out.println(num);
    //非静态方法中对于非静态方法的调用是省略了this
        this.haha();
        haha();//省略了this
        //使用类名.静态方法名调用静态方法
        Student.abc();
    }

    public void haha() {
        System.out.println("这是一个普通的实例方法");
        hehe();
    }

    //在静态方法中,不能存在this关键字。
    public static void abc() {
        System.out.println("这是一个静态方法abc");
        //this 本身代表的是一个该类的对象,对象是后来才有的。
        //this.name="你好"; 报错
        //this.haha(); 报错
    }
}

  • 对于提供main方法作为成员入口的这个类,在这个类中,我们一般不去定义成员变量和成员方法。将main方法设置为static,虚拟机通过类名可以调用,不需要实例化对象,更加方便、并且静态的main方法在内存中位置固定;将main方法设置为public,JVM才可以调用。
  • 由于静态只能访问静态,因此main中调用自定义方法需要static来修饰自定义方法,如果想要在静态main方法下调用非静态方法,可以new静态方法所在的类的对象,对象是实例,使用对象就可以在静态方法下调用非静态方法与变量

举例理解:

public class MyTest {
    static int num = 10;
    int a=10;
    public static void main(String[] args) {
        //静态变量使用类名调用赋值
        MyTest.num=20;
        System.out.println(MyTest.num);
        //静态方法使用类名调用
        MyTest.haha();
        //如果想要静态方法main中访问非静态方法:创建对象使用对象访问
        MyTest myTest1 = new MyTest();
        myTest1.hehe();//对象访问非静态方法

        num=10;//静态方法main中为静态变量赋值
        System.out.println(myTest1.num);//对象访问静态变量值
    }


    public static void haha(){
        System.out.println("haha");
    }
    public void hehe(){
        System.out.println("hehe");
    }
}

输出结果:
20
haha
hehe
10

三、静态变量和成员变量区别

  • 成员变量和局部变量的区别

局部变量:定义在方法中的变量,以及方法的形参。
成员变量:定义在类中方法外的变量

局部变量,属于方法,随着方法的调用产生,随着方法的调用完毕而消失。
成员变量:属于对象,随着对象的创建而产生,随着对象的销毁而销毁。

局部变量存储在栈内存,成员变量存储在堆内存。
局部变量,必须赋值才能使用,成员变量,有默认值。

  • 静态变量和成员变量区别

A:所属不同
静态变量属于类,所以也称为类变量
成员变量属于对象,所以也称为实例变量(对象变量)
B:内存中位置不同
静态变量存储于方法区的静态区
成员变量存储于堆内存
C:内存出现时间不同
静态变量随着类的加载而加载,随着类的消失而消失
成员变量随着对象的创建而存在,随着对象的消失而消失
D:调用不同
静态变量可以通过类名调用,也可以通过对象调用,推荐使用类名调用
成员变量只能通过对象名调用

四、静态常量与静态方法

Math类:

  • 由于Math类在java.lang包下,所以不需要导包。
  • 没有构造方法,因为它的成员方法与成员变量全部是静态的。

获取一个1-100之间的随机数,肿么办?
int number = (int)(Math.random()*100)+1;

静态常量的理解:
在 Math 类中定义了一个静态常量:

public class Hath
{
	public static final double PI = 3.14159265358979323846; 
}

  • 在程序中,可以采用 类名调用这个常量:Math.PI
  • 如果关键字 static 被省略, PI 就变成了 Math 类的一个实例常量,需要通过 Math 类的对象访问 PI,并且每一个 Math 对象都有它自己的一份 PI 拷贝。

静态方法理解:无需本类的对象即可调用此方法。
由于静态方法属于类由类调用,没有创建对象就不可以由对象来调用静态方法,因为Math类没有构造方法不能创建对象,因此Math中的方法不能由对象操作
例如:Math.pow(x, a)是计算x的a次幂。在运算时,不使用任何Math对象。

代码块

代码块就是被一对大括号括起来的范围,根据大括号的位置不同,将代码块分为:局部代码块、构造代码块、静态代码块、同步代码块(多线程);

  • 局部代码块(不常用):方法内用大括号括起来的代码,如果你希望及早的释放资源,你可以在方法内部定义变量;

  • 构造代码块(不常用):类中方法外、用大括号括起来的代码,每次创建对象时先执行构造代码块再执行构造方法,每次调用构造方法都执行构造代码块。

  • 静态代码块(常用):构造代码块加static,类中方法外被静态所修饰。静态代码块随着类加载进方法区而加载,类只加载一次因此只执行一次。创建对象时先执行静态代码块再执行构造代码块最后执行构造方法,如果再次创建对象就不会再执行静态代码块。静态代码块只能访问被静态所修饰的成员。
    静态代码块用于初始化操作,例如让类加载的时候读取配置文件,就会在静态代码块中写。

public class 代码块 {
    static {
        System.out.println("静态代码块");
    }
    {
        System.out.println("构造代码块");
    }

    public 代码块() {
        System.out.println("构造方法");
    }

    public static void main(String[] args) {
        代码块 one=new 代码块();
    }
}


执行结果:
静态代码块
构造代码块
构造方法

小练习:

A:看程序写结果
	public class StudentDemo {
    static {
        System.out.println("StudentDemo的静态代码块");  //1
    }

    public static void main(String[] args) {
        System.out.println("我是main方法"); //2

        Student s1 = new Student();
        Student s2 = new Student();
    }
}

class Student {
    static {
        System.out.println("Student 静态代码块"); //3
    }

    {
        System.out.println("Student 构造代码块"); //4 6
    }

    public Student() {
        System.out.println("Student 构造方法");//5 7
    }

执行结果:
StudentDemo的静态代码块
我是main方法
Student 静态代码块
Student 构造代码块
Student 构造方法
Student 构造代码块
Student 构造方法

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值