如果没有方法,会使得功能/业务逻辑相同的需求,需要除变量以外其他完全相同的代码,导致代码不能复用,过于冗余。
而方法的作用就在于将此功能/业务代码只需要写一次,之后再次遇到需要此功能的时候,只需直接调用方法即可。
方法定义在类体中,方法定义的先后顺序没有关系,均可以。
方法其实就是可以完成某个特定功能的并且可以被重复利用的代码片段。
方法调用时,如果一个方法1调用另一个方法2,而方法1和方法2在同一个类中,此时方法调用的类名.方法名可以将类名.省略。
此处若if中执行的是break,最终输出结果是1 2 3 4 hello world
若if中执行的是return,最终输出结果是 1 2 3 4.
因此break终止的离他最近的循环(也可以指定),然后再输出hello world结束。
而return是直径终止方法(此处为main方法),因此执行前4次循环后,直接return结束整个方法的执行,因此不会执行下面的helloworld 的输出。
总结:break:用来终止switch和理他最近的循环。
return:用来终止离他最近的一个方法。在同一个域中,return语句后面不能再编写其他代码。编写之后编译会报错。
方法区:静态成员、构造函数、常量池、线程池
栈内存:用于存储局部变量(方法内定义的),当数据使用完,所占空间会自动释放。当有方法被调用时,分配空间给此方法执行所用的内存空间和局部变量,压栈;一旦方法调用结束,将为此方法分配的空间释放,即出栈。
堆内存:数组和对象,通过new建立的实例均存放在堆内存中。
注意:方法重载只出现在同一个类当中,在不同类中的相同名的方法,不能算方法重载。
上图代码,m5()方法重复,编译会报错,因为定义了两个一样的m5方法,调用时会混淆。
注意:因此,方法重载与返回值类型以及修饰符类型无关。
方法重载只与方法名和形式参数列表有关。
面向对象的编程语言的三大特征:封装、继承和多态。(不仅限于java语言)
类名 变量名 = new 类名();
如:Student s1 = new Student();
注意:s1不是对象,s1叫做引用。因为s1中存储的是一个对象的地址,而不是一个数据。
而int i =100,其中i中存储着数据100,而不是100的地址。
java中的垃圾回收机制GC主要针对的是堆内存当中的垃圾数据。当一个Java对象没有任何引用指向该对象的时候,数据会被判定为垃圾,GC考虑将其回收释放掉。
注意:构造方法没有返回值类型,并且方法名与类名一样。
private:表示私有的,被这个关键字修饰后,该数据仅能在本类中访问。
总结:
带有static的方法:静态方法,可以通过类名.方法直接访问。
而不带有static的方法:实例方法(即对象方法),而所有与实例(对象)相关的都需要想new一个实例(对象)出来,然后通过引用.方法取访问。
即static的方法可以直接类名.方法访问,无需有对象。如上面的MethodTest.doSome()访问调用此方法。
而不带有static的方法,不能直接通过类名.方法访问,必须先new一个对象,然后通过引用.方法去访问。如上面的doOther(),不能直接用类名.方法(即MethodTest.doOther())调用,而是要先new一个MethodTest类型的对象mt,然后通过引用.方法(即mt.doOther())去调用。
回到封装,
注意:get/set方法都是实例(对象)方法,都是针对某个对象的访问。
封装的代码实现有两步:
第一步:属性私有化。
第二步:1个属性对外提供两个get和set方法。外部程序只能通过set方法进行修改,只能通过get方法读取。可以在set方法中设置关卡(如if判断等)来保证数据的安全性(不被恶意修改)。
静态变量在类加载在时初始化,不需要new对象,静态变量的内存空间就已经存在了。
并且静态变量存储在方法区。
注意:上图的最后有错误,一旦country设置为static静待变量,那么在构造方法中就不应该传参给country。因此,上图中最后的有参数的构造方法应该为:
public Chinese(String s1,String s2){
idCard = s1;
name = s2;
}
当设置country为静态变量后,其运行内存图为:
静态变量(是类级别的)在方法区,最先初始化;
局部变量(局部)存在栈中;
实例变量(对象级别的)存在堆中;
注意:通过使用 引用.静态变量名也可以访问静态变量,但是通过类名.实例变量名是不能访问实例变量的。但是不建议使用引用.静态变量来访问。
因此,
因此,
上面的代码执行的输出结果为:A B C Hello World!
因为需要在类加载的时候记录时间,那么如果这段代码写到mian方法中,那么就变成每次调用mian方法一次就记录了一次;如果写到构造方法中,那么每次new一个对象就记录一次。
因此,此时这段代码应该放在静态代码区。
这里的i是静态变量,在类加载时初始化,存在方法区。
同理,静态代码也是在类加载时执行的,也在方法区,因此此时静态代码区中是可以访问静态变量i的。
但是如果是一个实例变量(不带static),此时由于实例变量是在后续的构造方法new对象时才被声明赋值的,而静态代码区早于方法的执行,因此在静态代码区是无法访问实例变量的。
但是注意:如果static int i =100;放在静态代码区的后面,由于代码按先后顺序执行,当静态代码区执行时,静态变量i尚未被初始化,因此此时静态代码区是访问不了静态变量i的。
其实相当于,对于一个类中有多个构造方法,然后这多个构造方法的前半部分的代码都一样,就可以把相同的这一部分提取出来放在实例代码区。
因此,对于实例代码区中的代码,完全可以理解为:把其代码分别写入到每个构造方法的开头,效果是一样的。
注意:.后面跟的是一个单词,没有小括号,表示访问的是属性(变量);.后面跟的是一个单词,单词后面有小括号,表示访问的是方法。
变量分为局部变量和成员变量;
成员变量又分为实例变量和静态变量。
上图的情况为了区分实例变量和局部变量,this不能够省略,否则会出问题。
但是注意:如果使用this()调用,那么这行代码必须是调用this()的构造方法中的第一句。
对于第五条,对于所有的类,都默认继承了object类(sun公司已经定义好的)。
对于一个类,如:
class homeWork{
}
虽然看起来什么都没继承,但是其实默认省略了后面的extends Object。
注意:当system.out.println()中直接打印‘引用’,那么其实是默认打印引用.toString()方法的结果。
因为不同的类可能由不同的程序员编程,而当一个程序员调用另一个程序员编写的代码时,可能会传进不同的子类,而被调用的程序员不清楚会传进来什么子类,因此他需要使用instanceof判断,然后给出不同子类各自的后续执行方法分支(用if else来分开)。
对于返回值类型是引用数据类型来说,重写之后返回值可以变的更小,但是意义不大,因为实际开发中不会有人故意把重写后的返回值类型写小。
例子3:在例子2的子类中也添加一个和父类中同名的私有变量
此时的输出结果变为了:null 张三 null。
当子类中有和父类同名的方法时,如果想在子类中调用父类的(同名)方法必须加super.
B站 动力节点up主:Java_2020年版Java零基础视频教程(Java 0基础,Java初学入门)
视频链接:https://www.bilibili.com/video/BV1P7411V7nQ?p=1