美文网首页java基础
java类的基本构成

java类的基本构成

作者: LeoFranz | 来源:发表于2019-06-22 11:57 被阅读0次

导言

  • 面向对象思想理解:面向对象是一种程序设计规范,首先将万事万物当成对象来理解,他们都有各自的特征和行为方式,映射到程序设计层面就是每个对象都有表示各自的属性和功能,在我们处理问题时,建立不同的对象,不是为了实现一个步骤,而是描述一个事物在处理问题过程中的特性和行为。问题的解决通过对象间的交互完成。

  • 面向过程思想理解:着眼于每一个具体步骤,用函数和方法一步步将问题解决,整个流程串联起来实现具体功能。

  • 面向对象和面向过程的区别:
    面向过程 :面向过程性能比面向对象高。 因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考量因素的时候,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发。但是,面向过程没有面向对象易维护、易复用、易扩展。
    面向对象 :面向对象易维护、易复用、易扩展。 因为面向对象有封装、继承、多态性的特性,所以可以设计出低耦合的系统,使系统更加灵活、更加易于维护。但是,面向对象性能比面向过程低。
    另一个维度,当程序比较简单时面向过程设计更加简洁清晰,效率也高,但当功能越来越复杂,面向过程设计就愈发臃肿难以维护,所以面向对象思想更适合大型程序设计。

  • 类和对象的区别
    类是一组属性和行为的集合,是一个抽象的概念;
    对象是该类事物的具体表现形式,是实体。

java三大特性(???修改)

1.封装, 将对象的数据和行为整合在一起,对外部只暴露方法接口,隐藏具体实现,只要方法不变,对象内部数据如何变化并不直接影响其他类
2.继承,拓展一个已有的类时,拓展后的新类具有所拓展类的全部属性和方法,在新类中,只需要提供适用于这个新类的新方法和数据域即可
3.多态,同一个对象的引用可以指向不同的类型,即父类接口可以指向子类对象,这样可以提高代码的拓展性,但父类引用不能指向子类的特有内容,也不能用子类引用指向父类对象。

  • java对象的内存图
构造器

java中使用构造器创建对象并初始化部分状态;

补充的tip:
1.一个对象变量并没有真正包含一个对象,而仅仅是引用一个对象
2.对于包含多个文件的java程序编译,可以使用两个方法:
javac Classname*.java 通配符方法;
javac Classname.java 不会显示地编译该类使用的其他类文件,但是当编译器发现并没有需要的class文件时候,就会自动搜索并编译缺少的类文件。此外,编译器如果发现现有的.java文件比已有的.class文件新,就会自动重新编译这个文件。

构造器基本特性:

  • 与类同名
  • 每个类有一个以上的构造器
  • 构造器可以有0,1或者多个参数
  • 构造器没有返回值和返回值类型,连void也没有
  • 总是伴随着new一起调用

注意事项:

  • 系统会自动提供一个默认修饰符的无参构造方法,如果我们给了构造方法,无论有参数还是无参数,系统都不会默认提供了。
    从编码规范角度看,建议坚持至少创建无参构造器
  • 创建对象的时内存过程:
class Student {
    private String name = "Franz";
    private int age = 24;
    public Student() {
        name = "Leo";
        age = 25;    
    }
}

class StudentDemo {
public static void main(String[] orgs) {
    Student stu = new Student();
}

}

class文件加载到方法区,然后main方法进入栈区,创建指向对象的局部变量,然后在堆区创建新对象,其中的成员变量先被初始化为默认值,紧接着被赋予等号后初始值,然后才进入构造方法,被初始化为新的值,然后把堆内存的地址值赋值给stu变量。

  • 有时候就算按常规设置了私有域域和共有域访问器方法,仍然可能破坏封装性,如
class Employee {
    private Date hireDay;
    public Date getHireDay() {
        return hireDay;//这样外部获得该hireDay之后会调用Date额setTime方法改变该date
}
}

这种情况我们应该先对对象克隆,对象克隆是指存放在另一个位置上的对象副本。如果需要返回一个可变数据域的拷贝,就应该是使用clone.下面是修改后的代码

public Date getHireDay() {
    return hireDay.clone();
}
  • 被final标记的域必须在声明时初始化或者在构造器中初始化
  • 构造器不能被重写,因为子类不能继承父类的私有域和构造方法。但是构造器可以重载。

重载和重写的关系:
重载overload:发生在编译时。在一个类里面,方法名字相同,参数类型或个数或顺序不同,则被视为重载,这是判断是否重载的核心。返回值类型可能不同,访问修饰符可能不同,检查异常范围可能不同。
重载严格意义上并不属于多态,重载的具体实现是:编译器根据不同的参数表,对同名函数的名称做修饰,然后这些同名函数就变成了不同的函数。对重载函数的调用,在编译期间就已经确定了,是静态的(注意!是静态的),因此,重载和多态无关。

重写override:发生在运行时。重写是子类对父类被允许访问的方法实现过程进行重新编写,函数名和参数列表必须和父类方法相同。返回值范围小于等于父类,访问权限必须大于等于父类,抛出的异常范围小于等于父类,final、static声明的方法不能被重写,构造方法不能被重写,private声明的方法不能被重写。
真正和多态相关的是重写,当子类重写了父类中的函数后,父类的 指针,根据赋值给它不同的子类对象指针,动态的调用属于子类的该函数,这样在编译期间是无法确定的,只有在运行期间,才会把动态链接转变为直接引用
同名同签名的方法,父类方法如果加上了static修饰符,子类也应该加上static修饰符,这由于不涉及对象算不上重写,至于为什么?????

  • 当一个变量被用来表示一个类的属性时候,才被规定为成员变量。变量的使用应该遵循影响范围越小越好原则,为了能被及时回收,防止夜长梦多。
  • 子父类构造器的关系?
  • 类加载过程,关于构造器、成员变量、静态代码块、代码块等?
静态域和静态方法

用于修饰类中被所有对象共享的变量或方法,它随着类的加载而加载,优先于对象存在。所以main方法是静态的,因为它被虚拟机调用,不需要创建对象。
注意点:

  • 由于静态域和方法不单独属于任何对象,所以在静态方法中不能有this关键字,静态方法只能访问静态的成员变量或方法。
  • 静态成员变量和方法存在方法区的静态区(成员变量存储于堆内存),当在堆中创建对象时候,不同对象中的静态引用指向同一个静态区的数据。
  • 静态变量的生命周期同步于类,成员变量的生命周期同步于对象

关于main方法的补充:
public修饰符,因为需要被jvm直接调用,访问权限要最大;
static,因为不需要创建对象
void,方法的返回值是给调用者,jvm不需要main方法的调用值
string[] args,命令行参数,输入格式为java classname command line parameters, 一般我们没输入这个参数,所以系统接收的是一个长度为0的字符串数组。

补充,java方法参数是值传递还是引用传递的问题

首先看基本数据类型参数
public static void rise(double salary) {
        salary = salary * 3;
    }

    public static void main(String[] args) {
        double salary = 100;
        rise(salary);
        System.out.println(salary);
    }
//输出为100

然后看对象引用作为参数时成员变量的变化
public static void growUp(Student student) {
        student.setAge(student.getAge() + 1);
    }

    public static void main(String[] args) {
        Student student = new Student(15);
        System.out.println(student.getAge());
        growUp(student);
        System.out.println(student.getAge());
    }
//输出为15.0,16.0.

再看最后一种情况
 public static void swamp(Student a, Student b) {
        Student temp = a;
        a = b;
        b = temp;
        System.out.println(a.getAge()+"   "+b.getAge());
    }

    public static void main(String[] args) {
        Student a = new Student(15.5);
        Student b = new Student(16.5);
        swamp(a,b);
        System.out.println(a.getAge()+"   "+b.getAge());
    }
//输出结果
16.5   15.5
15.5   16.5

结论一:方法不能修改基本数据类型的参数;
结论二:传入对象引用作为参数时能够改变对象的状态,因为方法参数和传入的对象引用同时指向同一个对象;
结论三:传入对象引用并不能被改变指向
根本结论:java语言是按值调用,方法得到的是所有参数值的一个拷贝,方法不能修改传递给它的任何参数变量的内容。

补充,java内存图解

访问其他包的共有类两种方法,类前加前缀或者导包;

  • 注意号只表示导入了单个包中的所有类,不能使用import java.或者import java..表示导入了以java为前缀的所有包。
  • 当有重名的类时,如同时import了java.util.和java.sql.这就需要再加句import java.util.Date表示使用的是该包下的Date,如果两个都想要,那么在类前缀前加包名。
  • 静态导入,import static java.lang.System.*,这样就能在程序中使用System类的静态内容,如out.println();此外,还可以导入特定的方法或方法域,import static java.lang.System.out,这个用的很少。
  • 如果类文件没有指定package语句,就会被放到一个默认包中
  • 编译器编译java文件,而解释器加载.class文件。使用编译命令时需要指定完整的包名,如javac com/***/****/Student.java,此时编译器还会自动查找同类名下使用到的其他文件并编译。
代码块
  • 局部代码块 在方法中出现,限定变量声明周期,及时释放无用变量,提高内存利用率
  • 构造代码块 在类中方法和构造函数之外出现,用于对每个对象进行与构造方法无关的初始化,每次创建对象都会执行,并且在构造方法前执行。
  • 静态代码块 与之前两种形式上区别就是多了个static,对类进行初始化,在所有代码块中最先执行,但只执行一次。在main方法所在的类中,该类的静态代码块仍然领先于main方法执行,所以方法加载是在类加载之后的。

相关文章

  • java类的基本构成

    导言 面向对象思想理解:面向对象是一种程序设计规范,首先将万事万物当成对象来理解,他们都有各自的特征和行为方式,映...

  • [Java初探02]——Java语言基础

    本篇博文就Java语言的一些基本元素进行一些记录和阐述,主要讲解一下Java语言的一些基本构成元素和Java的主类...

  • Java JVM基本构成

    JVM基本构成: 从上图可知,JVM主要包括四个部分: 1.类加载器(ClassLoader) 在JVM启动时或者...

  • Java面向对象概述和三大特性

    Java 是面向对象的高级编程语言,类和对象是 Java 程序的构成核心。围绕着 Java 类和 Java 对象,...

  • 学习Java编程面向对象的五大基本原则

    Java 是面向对象的高级编程语言,类和对象是 Java 程序的构成核心。围绕着 Java 类和 Java 对象,...

  • 《Oracle Java SE编程指南》04-02:类

    内容导航: 前言 1、Java类的基本结构 Java应用都是由若干个Java类组成,因此,深入学习类的基本结构,将...

  • JavaExam

    Java基本编译操作 类,对象 类What is a Java class?➢ A template for a ...

  • static关键字

    Java中static可以修饰类、变量、方法甚至可以构成静态块,让我们来了解下它们各自的使用以及加载顺序吧。 基本...

  • 刘铁猛C#第5讲(1)构成C#语言的基本元素

    构成C#语言的基本元素 构成C#语言的基本元素和构成其他语言的基本元素有所区别。 C#跟Java很像,是因为两者的...

  • 类的基本构成与实例化

    1. 类名: 1.1 命名方式:class 类名:1.2 类继承:class 类名(父类): 2. 类变量: 2....

网友评论

    本文标题:java类的基本构成

    本文链接:https://www.haomeiwen.com/subject/hykksqtx.html