• Java 类和对象


    类的定义

    0.成员变量又名字段又名属性又名成员属性

    1. 类的定义建议使用大驼峰的命名方式,如BookRecord,BookList...

    2.一个Java文件建议只包含一个类,这是Java开发的一个基本准则

    3.public修饰的类的名字要与java文件名相同。

    4.与C++不同的是,Java中需要对每一个成员指定访问权限,而不是若干成员。

    类定义的基本示例:所以 此Book类定义在Book.java文件中

    1. public class Book {
    2. private String bookName;
    3. private String authorName;
    4. private double price;
    5. private String type;
    6. private boolean isBorrowed;
    7. public Book(String bookName, String authorName, double price, String type) {
    8. this.bookName = bookName;
    9. this.authorName = authorName;
    10. this.price = price;
    11. this.type = type;
    12. }
    13. public void setBookName(String bookName) {
    14. this.bookName = bookName;
    15. }
    16. public String getBookName() {
    17. return bookName;
    18. }
    19. public void setAuthorName(String authorName) {
    20. this.authorName = authorName;
    21. }
    22. public String getAuthorName() {
    23. return authorName;
    24. }
    25. public void setPrice(double price) {
    26. this.price = price;
    27. }
    28. public double getPrice() {
    29. return price;
    30. }
    31. public void setType(String type) {
    32. this.type = type;
    33. }
    34. public String getType() {
    35. return type;
    36. }
    37. public boolean isBorrowed() {
    38. return isBorrowed;
    39. }
    40. public void setBorrowed(boolean borrowed) {
    41. isBorrowed = borrowed;
    42. }
    43. @Override // 重写Object类的toString方法。
    44. public String toString() {
    45. return "Book{" +
    46. "bookName='" + bookName + '\'' +
    47. ", authorName='" + authorName + '\'' +
    48. ", price=" + price +
    49. ", type='" + type + '\'' +
    50. ", isBorrowed:" + (isBorrowed ?"Yes":"No") +
    51. '}';
    52. }
    53. }

    类的实例化

    比如:

    Book book = new Book("三国演义","施耐庵",18,"小说");

    book可以看作这个对象的别名,可以直接使用.运算符访问其可访问的成员。

    这里与C++相比算是有些特殊的,Java中除了基本数据类型。 String类型,数组类型,以及类类型都是引用类型。也就是只能通过new关键字来在堆区开辟一个新的类对象。而接收这个类对象的就是类对象的引用类型。底层存储的是类对象的地址。

    如图,在堆上开辟一个对象,会存储对象的非静态的数据成员。而成员函数等代码段会加载到方法区,这里也会存储静态成员,静态方法的代码段。而那个存储着对象地址的引用变量会存储在这条语句的栈帧中,也就是栈区。

    而那些定义在成员函数内的变量属于局部变量,存储在栈区内,也就是成员函数的栈帧内。

    Book book2 = null;

    这样的语句也是合理的,null表示此Book引用不指向任何对象。 

    引用类型并不一定在栈上

    如图,如果数据成员为 Book book = new Book(); 时 

    static关键字

    static修饰成员变量

    1、static修饰的成员变量 又叫做类变量 存储在方法区,这种变量每个类共享一个,这是不依赖于对象的,不定义对象的情况下,也可以访问类的静态成员。

    2、使用类名来访问静态数据成员,对象也可以但不建议。

    static修饰成员函数

    1、同样,被static修饰的成员方法是属于类的,而不属于某一个对象。

    2、静态方法内不可以访问任何和对象相关的成员,包括普通数据成员和普通成员函数,因为静态方法是与对象不相干的,而普通数据成员和普通成员方法是与对象有关的。

    3、建议使用类名访问静态成员

    4、static修饰的数据成员只能定义在类内方法外,普通成员函数和静态成员函数内都不能定义static数据成员。因为它是类变量。

    思考

    main函数是public static void main(String[] str) {}  所以有时我们在main函数所在类内定义一个其他测试函数时,需要定义为static的,因为静态的main不能调用普通成员函数,因为它是与对象相关的。

    即:与.java文件名同名的类内定义一些可以让main函数调用的方法时,必须写上static

    类成员初始化问题

    Java同样支持类内初始值,也支持构造函数,而如果没有类内初始值,也没有构造函数初始化,就会使用默认值,引用类型默认为null,int为0,boolean为false等。 

    构造函数的初始化后于类内初始值。

    this指针

    在类的成员方法内,可以使用this指针,this指针为调用此方法的对象的引用,可以用此访问其他数据成员和其他普通成员函数。

    更多使用在构造函数中,用于指定数据成员。以及继承关系中,如果子类和父类有同名数据成员,this.num 表示访问自己的那个num  而super.num  表示访问父类的那个。

    第三种this(); 类似于C++中的构造函数的托管,也就是在一个构造函数中调用另一个构造函数来进行部分或者全部的数据成员初始化工作。 

    规则:必须放在构造函数内的第一行且只能调用一次super。super(s,10);表示调用另一个两个参数的构造函数来对某些数据成员进行初始化工作。

    代码块

    字段的初始化方式有: 1. 就地初始化 2. 使用构造方法初始化 3. 使用代码块初始化

    代码块:使用{}定义的一段代码,根据此代码块的位置不同而分为不同的代码块。

    普通代码块:

    定义在方法中的代码块.

    1. public class Main{
    2. public static void main(String[] args) {
    3. { //直接使用{}定义,普通方法块
    4. int x = 10 ;
    5. System.out.println("x1 = " +x);
    6. }
    7. int x = 100 ;
    8. System.out.println("x2 = " +x);
    9. }
    10. }

    构造代码块

    定义在类中的代码块(不加修饰符)。也叫:实例代码块。

    构造代码块一般用于初始化实例成员变量。(即非静态成员变量。

    1. class Person{
    2. private String name;//实例成员变量
    3. private int age;
    4. private String sex;
    5. public Person() {
    6. System.out.println("I am Person init()!");
    7. }
    8. //实例代码块
    9. {
    10. this.name = "bit";
    11. this.age = 12;
    12. this.sex = "man";
    13. System.out.println("I am instance init()!");
    14. }
    15. public void show(){
    16. System.out.println("name: "+name+" age: "+age+" sex: "+sex);
    17. }
    18. }
    19. public class Main {
    20. public static void main(String[] args) {
    21. Person p1 = new Person();
    22. p1.show();
    23. }
    24. }
    25. // 运行结果
    26. I am instance init()!
    27. I am Person init()!
    28. name: bit age: 12 sex: man

    这里实例代码块和构造函数的优先顺序就不讨论了。

    其实这个实例代码块的名字很有意思,因为普通数据成员又称实例数据成员,而实例代码块的主要作用就是初始化实例成员。

    静态代码块

    使用static定义的代码块。一般用于初始化静态成员属性。同样定义在类内,方法外

    1. class Person{
    2. 比特科技
    3. private String name;//实例成员变量
    4. private int age;
    5. private String sex;
    6. private static int count = 0;//静态成员变量 由类共享数据 方法区
    7. public Person(){
    8. System.out.println("I am Person init()!");
    9. }
    10. //实例代码块
    11. {
    12. this.name = "bit";
    13. this.age = 12;
    14. this.sex = "man";
    15. System.out.println("I am instance init()!");
    16. }
    17. //静态代码块
    18. static {
    19. count = 10;//只能访问静态数据成员
    20. System.out.println("I am static init()!");
    21. }
    22. public void show(){
    23. System.out.println("name: "+name+" age: "+age+" sex: "+sex);
    24. }
    25. }
    26. public class Main {
    27. public static void main(String[] args) {
    28. Person p1 = new Person();
    29. Person p2 = new Person();//静态代码块是否还会被执行?
    30. }
    31. }

    静态代码块不管生成多少个对象,其只会执行一次,且是最先执行的。

    静态代码块执行完毕后, 实例代码块(构造块)执行,再然后是构造函数执行。

    总而言之:先静态,后实例,再构造函数。且静态代码块只执行一次,只能访问与this无关的成员。

    真没意思 

  • 相关阅读:
    【主流技术】聊一聊消息队列 RocketMQ 的基本结构与概念
    学之思项目第一天-完成项目搭建
    好消息,完整版的jwt鉴权机制来了呦
    人体器官衰老表公布,对照着保养,也许会比别人老得慢
    微信小程序 |从零实现酷炫纸质翻页效果
    OSINT技术情报精选·2024年5月第4周
    改变光标形状的多种方式
    安全防御——APT
    C++数据结构补充(线性表及其链式存储结构:单链表)
    动态规划-杨辉三角(leetcode)
  • 原文地址:https://blog.csdn.net/i777777777777777/article/details/125604586