类的格式:
class Student{ //定义变量 int age; String name; //定义方法 public void eat(){ System.out.println("eat"); } }
属性的调用:
class Student{ //定义变量 int age; String name; //定义方法 public void eat(){ System.out.println("eat"); } } class StudentDemo{ public static void main( String[] args){ Student s = new Student(); //属性赋值 s.age =19; s.name = "zym"; System.out.println(s.age+s.name); //函数调用 s.eat(); } }
成员变量和局部变量:
区别:
成员变量和局部变量的区别?
A:在类中的位置不同
成员变量:在类中方法外
局部变量:在方法定义中或者方法声明上
B:在内存中的位置不同
成员变量:在堆内存
局部变量:在栈内存
C:生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
D:初始化值不同
成员变量:有默认初始化值
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
注意事项:
局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
类参数的问题:
//形式参数是基本类型 class Demo { public int sum(int a,int b) { return a + b; } }
//形式参数是引用类型
class Student {
public void show() {
System.out.println("我爱学习");
}
}
class StudentDemo {
//如果你看到了一个方法的形式参数是一个类类型(引用类型),这里其实需要的是该类的对象。
public void method(Student s) { //调用的时候,把main方法中的s的地址传递到了这里 Student s = new Student();
s.show();
}
}
匿名对象:
就是没有名字的对象,有点想python中的lamba。
应用场景:
A:调用方法,仅仅只调用一次的时候。
注意:调用多次的时候,不适合。
那么,这种匿名调用有什么好处吗?
有,匿名对象调用完毕就是垃圾。可以被垃圾回收器回收。
B:匿名对象可以作为实际参数传递
class Student { public void show() { System.out.println("我爱学习"); } } class StudentDemo { public void method(Student s) { s.show(); } } class NoNameDemo { public static void main(String[] args) { //带名字的调用 Student s = new Student(); s.show(); s.show(); System.out.println("--------------"); //匿名对象 //new Student(); //匿名对象调用方法 new Student().show(); new Student().show(); //这里其实是重新创建了一个新的对象 System.out.println("--------------"); //匿名对象作为实际参数传递 StudentDemo sd = new StudentDemo(); //Student ss = new Student(); //sd.method(ss); //这里的s是一个实际参数 //匿名对象 sd.method(new Student()); //在来一个 new StudentDemo().method(new Student()); } }
封装:
隐藏对象的属性和实现细节,仅对外提供公共访问方式。
用私有修饰符 private实现
Private关键字:
可以修饰成员变量和方法,被修饰之后只能被本类进行访问,或者操作
也可以给构造方法进行pricate修饰,可以让类无法被实例化,只能使用类名进行
方法的调用。
this关键字:
相当于python类中的self,
方法被那个对象调用,this就代表那个对象。
可以解决局部变量隐藏成员变量
class Student { private String name; private int age; public String getName() { return name; //这里其实是隐含了this } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
this调用构造方法:
public class Person1{ private String name; public Person1(){ this.print(); } public void print(){ System.out.println("xxx"); } public Person1(String name){ this();//调用无参构造方法必须在第一行 } }
构造方法:
给对象的数据进行初始化
格式:
方法名与类名相同
没有返回值类型,连void都没有
没有具体的返回值
构造方法的注意事项:
如果我们没有给出构造方法,系统将自动提供一个无参构造方法。
如果我们给出了构造方法,系统将不再提供默认的无参构造方法。
注意:这个时候,如果我们还想使用无参构造方法,就必须自己给出。建议永远自己给出无参构造方法
因为构造是一个方法,所以也有重载
class Student { private String name; private int age; public Student() { //System.out.println("我给了,你还给不"); System.out.println("这是无参构造方法"); } //构造方法的重载格式 public Student(String name) { System.out.println("这是带一个String类型的构造方法"); this.name = name; } public Student(int age) { System.out.println("这是带一个int类型的构造方法"); this.age = age; } public Student(String name,int age) { System.out.println("这是一个带多个参数的构造方法"); this.name = name; this.age = age; } public void show() { System.out.println(name+"---"+age); } }
static关键字:
针对多个对象有共同的这样的成员变量值的时候,
public static xxx
相当于是个全局变量,也叫静态变量。
Java就提高了一个关键字来修饰:static。
class Person { //姓名 String name; //年龄 int age; //国籍 //String country; static String country; public Person(){} public Person(String name,int age) { this.name = name; this.age = age; } public Person(String name,int age,String country) { this.name = name; this.age = age; this.country = country; } public void show() { System.out.println("姓名:"+name+",年龄:"+age+",国籍:"+country); } } class PersonDemo { public static void main(String[] args) { //创建对象1 Person p1 = new Person("邓丽君",16,"中国"); p1.show(); //创建对象2 //Person p2 = new Person("杨幂",22,"中国"); //p2.show(); Person p2 = new Person("杨幂",22); p2.show(); //创建对象3 //Person p3 = new Person("凤姐",20,"中国"); //p3.show(); Person p3 = new Person("凤姐",20,"美国"); p3.show(); System.out.println("--------------------------"); p3.country = "美国"; p1.show(); p2.show(); p3.show(); } }
特点:
/* static的特点:(它可以修饰成员变量,还可以修饰成员方法) A:随着类的加载而加载 回想main方法。 B:优先于对象存在 C:被类的所有对象共享 举例:咱们班级的学生应该共用同一个班级编号。 其实这个特点也是在告诉我们什么时候使用静态? 如果某个成员变量是被所有对象共享的,那么它就应该定义为静态的。 举例: 饮水机(用静态修饰) 水杯(不能用静态修饰) D:可以通过类名调用 其实它本身也可以通过对象名调用。 推荐使用类名调用。 静态修饰的内容一般我们称其为:与类相关的,类成员
注意:非static声明的方法可以去调用static声明的属性或者方法。
但是static声明的方法是不能调用非static类型声明的属性或方法的。
*/ class Student { //非静态变量 int num = 10; //静态变量 static int num2 = 20; }
内存的进行过程:
静态方法的注意事项:
static关键字注意事项
在静态方法中是没有this关键字的
如何理解呢?
静态是随着类的加载而加载,this是随着对象的创建而存在。
静态比对象先存在。
静态方法只能访问静态的成员变量和静态的成员方法
静态方法:
成员变量:只能访问静态变量
成员方法:只能访问静态成员方法
非静态方法:
成员变量:可以是静态的,也可以是非静态的
成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
简单记:
静态只能访问静态。
静态变量联合成员变量的区别:
所属不同:
静态变量属于类,所以也称为类变量
成员变量属于对象,所以也称为实例变量(对象变量)
内存中的位置不同:
静态变量存储于方法区的静态区
成员变量存储于内存
内存出现的时间不同:
静态变量随着类的加载而加载,随着类的消失而消失
成员变量随着对象的创建而存在,随着对象的消失而消失
调用不同:
静态变量可以通过类名调用,也可以通过对象调用。
成员变量只能通过对象名调用
main方法的格式:
main方法的格式讲解:
public static void main(String[] args) {...}
public:公共的,访问权限是最大的。由于main方法是被jvm调用,所以权限要够大。
static:静态的,不需要创建对象,通过类名就可以。方便jvm的调用。
void:因为我们曾经说过,方法的返回值是返回给调用者,而main方法是被jvm调用。你返回内容给jvm没有意义。
main:是一个常见的方法入口。
String[] args:这是一个字符串数组。值去哪里了?
这个东西到底有什么用啊?怎么给值啊?
这个东西早期是为了接收键盘录入的数据的。
格式是:
java MainDemo hello world java
帮助文档的制作:
/** * 这是针对数组进行操作的工具类 * @author xxx * @version yyy */ public class ArrayTool { //把构造方法私有,外界就不能在创建对象了 /** * 这是私有构造 */ private ArrayTool(){} /** * 这是遍历数组的方法,遍历后的格式是:[元素1, 元素2, 元素3, ...] * @param arr 这是要被遍历的数组 */ public static void printArray(int[] arr) { System.out.print("["); for(int x=0; x<arr.length; x++) { if(x == arr.length-1) { System.out.println(arr[x]+"]"); }else { System.out.print(arr[x]+", "); } } } /** * 这是获取数组中最大值的方法 * @param arr 这是要获取最大值的数组 * @return 返回数组中的最大值 */ public static int getMax(int[] arr) { int max = arr[0]; for(int x=1; x<arr.length; x++) { if(arr[x] > max) { max = arr[x]; } } return max; } /** * 获取指定元素在数组中第一次出现的索引,如果元素不存在,就返回-1 * @param arr 被查找的数组 * @param value 要查找的元素 * @return 返回元素在数组中的索引,如果不存在,返回-1 */ public static int getIndex(int[] arr,int value) { int index = -1; for(int x=0; x<arr.length; x++) { if(arr[x] == value) { index = x; break; } } return index; } }
之后的查看方法可以使用,例如:
C:> javadoc -d C:\home\html -sourcepath C:\home\src java.awt java.awt.event
-d为你指定生成帮助文件的目录,没有他会给你创建,-sourcepath是源文件的路径,
后面可以是1个或者多个文件。
之后进入那个目录,查看index.html的那个文件。
代码块
代码块:在Java中,使用{}括起来的代码被称为代码块。
根据其位置和声明的不同,可以分为
局部代码块:
局部位置,用于限定变量的生命周期。方法中定义的代码块
构造代码块:
在类中的成员位置,用{}括起来的代码。每次调用构造方法执行前,都会先执行构造代码块。
作用:可以把多个构造方法中的共同代码放到一起,对对象进行初始化。
静态代码块:
在类中的成员位置,用{}括起来的代码,只不过它用static修饰了。
作用:一般是对类进行初始化。
class Code { static { int a = 1000; System.out.println(a); } //构造代码块 { int x = 100; System.out.println(x); } //构造方法 public Code(){ System.out.println("code"); } //构造方法 public Code(int a){ System.out.println("code"); } //构造代码块 { int y = 200; System.out.println(y); } //静态代码块 static { int b = 2000; System.out.println(b); } } class CodeDemo { public static void main(String[] args) { //局部代码块 { int x = 10; System.out.println(x); } //找不到符号 //System.out.println(x); { int y = 20; System.out.println(y); } System.out.println("---------------"); Code c = new Code(); System.out.println("---------------"); Code c2 = new Code(); System.out.println("---------------"); Code c3 = new Code(1); } }
代码块的执行顺序:
静态代码块 -- 构造代码块 -- 构造方法
静态代码块:只执行一次,因为随着类的加载而加载
构造代码块:每次调用构造方法都执行,对象方法
继承:
继承的格式:
使用关键字extends 类
class 子类名 extends 父类名 {}
class Father { public void method(){ System.out.println("我是老子"); } } class Son extends Father {}
这里注意java中没有多继承的概念,只有单继承。
继承的利与弊:
好处:
A:提高了代码的复用性
B:提高了代码的维护性
C:让类与类之间产生了关系,是多态的前提
类与类产生了关系,其实也是继承的一个弊端:
类的耦合性增强了。
开发的原则:低耦合,高内聚。
耦合:类与类的关系
内聚:就是自己完成某件事情的能力
注意:
子类只能继承父类的非私有变量,方法。
子类不能继承父类的构造方法,但是需要使用super来进行访问。(默认的是有super()的)
变量名字一样的话,后面的覆盖前面的。
super方法和this方法的区别:
this和super的区别?
分别是什么呢?
this代表本类对应的引用。
super代表父类存储空间的标识(可以理解为父类引用,可以操作父类的成员)
怎么用呢?
A:调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
B:调用构造方法
this(...) 调用本类的构造方法
super(...) 调用父类的构造方法
C:调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法
继承中的构造方法的关系:
继承中构造方法的关系
A:子类中所有的构造方法默认都会访问父类中空参数的构造方法
B:为什么呢?
因为子类会继承父类中的数据,可能还会使用父类的数据。
所以,子类初始化之前,一定要先完成父类数据的初始化。
注意:子类每一个构造方法的第一条语句默认都是:super();
继承中的构造方法的关系(父类没有无参数的构造方法):
如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
报错。
如何解决呢?
A:在父类中加一个无参构造方法
B:通过使用super关键字去显示的调用父类的带参构造方法
C:子类通过this去调用本类的其他构造方法
子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化。
注意事项:
this(...)或者super(...)必须出现在第一条语句上。
如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。
class Father { /* public Father() { System.out.println("Father的无参构造方法"); } */ public Father(String name) { System.out.println("Father的带参构造方法"); } } class Son extends Father { public Son() { super("随便给"); System.out.println("Son的无参构造方法"); //super("随便给"); } public Son(String name) { //super("随便给"); //this(); System.out.println("Son的带参构造方法"); } public Son(int age) { //super("随便给"); this(); System.out.println("Son的带参构造方法"); } }
类继承方法的重写:
方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法。
这样,即沿袭了父类的功能,又定义了子类特有的内容。
如何使用父类的功能呢?通过super关键字调用
这里注意:
子类重写父类方法的时候,最好声明一模一样。
@Override
帮你检验你的重写的方法是否覆盖了父类的方法。
类的初始化过程:
一个类的初始化过程
成员变量的初始化
默认初始化
显示初始化
构造方法初始化
内部类:
在类内部也可以定义另一个类。如果在类Outer的内部再定义一个类Inner,此时类Inner就称为内部类,而类Outer则称为外部类。
标识符 class 外部类的名称{ // 外部类的成员 标识符 class 内部类的名称{ // 内部类的成员 } }
static关键字修饰:
用static可以声明属性或方法,而用static也可以声明内部类,
用static声明的内部类则变成外部类,但是用static声明的
内部类不能访问非static的外部类属性。
在外部访问内部类:
外部类.内部类 内部类对象 = 外部类实例.new 内部类() ;
单例模式:
class Person1{ private Person1 P = new Person1(); public Person1(){}; public Person1 get_obj(){ //这里注意,这种类型是表示返回的是一个独享 return P; } }; public class java_start{ public static void main(String[] args){ }
class Person1{ static private Person1 P = null; private Person1(){}; public static Person1 get_obj(){ if (P==null){ P = new Person1(); } return P; } }; public class java_start{ public static void main(String[] args){ Person1 s = Person1.get_obj(); } }