文章目录
类和对象的详细笔记加代码
1、对象的定义:
对象是看得见的,比如学生张三
万事万物皆为对象
对象由属性和行为组成
对象的属性描述的是对象的特征
对象的行为指的是对象具有哪些功能
在java中,属性和行为又叫做成员变量和方法
2、类的定义:
是抽象的,比如一个班的学生,他们都有名字和学号
类是对具有相同属性和特征的同一对象的抽象
3、对象的创建过程:
从现实世界中—>抽象出属性和行为—>封装成类—>创建对象
创建一个Student类
package test_oop;
public class Student {
//类定义了属性和行为
//属性
String name;
int sno;
//行为
public void study(){
System.out.println("学习");
}
}
再创建一个测试类
package test_oop;
import java.sql.SQLOutput;
//测试类
public class Test {
public static void main(String[] args) {
int a = 10;
//1.类是一种自定义的数据类型(引用类型),类似于int (类型) a(变量名) = 10(赋值)
//2.类是对象的模板
//创建对象后,该对象的属性会默认赋值
Student student1 = new Student();
System.out.println("student1.name:"+student1.name);//student1.name:null
System.out.println("student1.sno:"+student1.sno);//student1.sno:0
//可以再赋值,覆盖默认值
student1.name="张三";
student1.sno=001;
System.out.println("student1.name:"+student1.name);
System.out.println("student1.sno:"+student1.sno);
System.out.println("---------------");
//声明变量
int a2;
//后赋值
a2 = 20;
//创建对象也可以先声明,再赋值
Student student2;
student2 = new Student();
student2.name = "李四";
student2.sno = 002;
System.out.println("student2.name:"+student2.name);
System.out.println("student2.sno:"+student2.sno);
}
}
4、类的定义顺序:
1.先定义一个类
public class 类名{}
2.定义类的属性(成员变量)
访问修饰符 类型 变量名;
3.定义类的方法
访问修饰符 返回值类型 方法名(参数){}
注意:一个类中可以只定义属性或者方法,两者也可以同时定义,若什么也不定义的话,这个类就没有意义。
5、静态方法和非静态方法被测试类调用的区别
静态方法:类名.方法名()
非静态方法:对象.方法名()
有以下举例:
package test_oop;
public class Car {
//成员变量
String brand;
double price;
//非静态方法
public void sumPrice(int num){//返回值类型为void
System.out.println("汽车总价格为:"+num*price);
}
//静态方法
public static void run(){
System.out.println("汽车在跑---");
}
}
package test_oop;
import java.util.Scanner;
public class TestCar {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
Car car = new Car();
car.price = 200000;
int num = scan.nextInt();
System.out.println("买了"+num+"辆汽车");
//调用非静态方法 对象.方法
car.sumPrice(num);
//调用静态方法 类名.方法
Car.run();
}
}
6、一个源文件中可以有多个类吗?
在一个源文件中可以有多个类,但只有一个是public修饰的类,public修饰的类的名称一定要与源文件的名字一样。
举例如下:
package test_oop;
public class TestClass {//public修饰的类
}
class MyTest{}
class MyTest1{}
class MyTest2{}
如果一个源文件中没有public修饰的类
则可以命名与类名不同的名称
package test_oop;
class MyTest{}
class MyTest1{}
class MyTest2{}
7、引用和实例(对象)的区别
引用保存了对象的首地址,创建一个实例(对象)的过程,也就是实例化的过程。
过程:在new 构造方法()的过程中,为创建的对象分配堆内存,内存中存储了这个对象的属性和属性值。
在下面的测试类中 stu1和stu2是不同的对象,它们的的地址值不通过
public class Test2 {
public static void main(String[] args) {
Student stu1 = new Student();
System.out.println("stu1的地址:"+stu1);
//stu1的地址:test_oop.Student@4554617c
Student stu2 = new Student();
System.out.println("stu2的地址:"+stu2);
//stu2的地址:test_oop.Student@74a14482
}
}
8、String类型的地址(==)和值(equals)的比较
package test_oop;
public class TestString {
public static void main(String[] args) {
String s1 = new String("name");
String s2 = new String("name");
System.out.println("s1=" + s1);//s1=name String类中重写了toString 方法
System.out.println("s2=" + s2);//s1=name
System.out.println("s1 == s2" + (s1 == s2));//s1 == s2false 比较的是地址
System.out.println("s1.equals(s2)"+s1.equals(s2));//s1.equals(s2)true 比较的是值
}
}
9、自定义类型的equals()重写,toString()重写
在Student类中重写equals(),toString()
package test_oop;
public class Student {
//类定义了属性和行为
//属性
String name;
int sno;
//行为
public void study(){
System.out.println("学习");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSno() {
return sno;
}
public void setSno(int sno) {
this.sno = sno;
}
// 重写toString()输出stu对象的时候自动调用
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sno=" + sno +
'}';
}
//重写equals(),调用的时候比较的是stu1.name和stu2.name
@Override
public boolean equals(Object obj) {
Student stu = (Student) obj;
return name.equals(stu.name);
}
}
在测试类中测试重写的方法
package test_oop;
public class TestToStringEquals {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setName("stu2");
Student stu2 = new Student();
stu2.setName("stu2");
//没有重写时,输出的是对象的地址,比较的是对象的地址
/*System.out.println("stu1:"+stu1);//stu1:test_oop.Student@4554617c
System.out.println("stu2:"+stu2);//stu2:test_oop.Student@74a14482
System.out.println(stu1.equals(stu2));//false*/
//重写后,输出的是stu1.sno..对象的名字,学号,比较的是名字
System.out.println("stu1:"+stu1);//stu1:Student{name='stu2', sno=0}
System.out.println("stu2:"+stu2);//stu2:Student{name='stu2', sno=0}
System.out.println(stu1.equals(stu2));//true
}
}
10、引用类型 数组和自定义对象的共同点:
两者都是引用类型,在引用2=引用1时,两者指向的是同一个地址,两者的值相互影响,对象1的值改变,对象2中的值同样要改变
参考测试代码
package test_oop;
public class TestArrayClass {
public static void main(String[] args) {
//数组和自定义对象的共同点
int[] a = new int[3];
a[0] = 10;
changeArray(a);//相当于 int b = a
System.out.println(a[0]);//20
Student student = new Student();
student.name = "lili";
changeStudent(student);//相当于 Student student2 = student
System.out.println(student.name);//zs
}
/**
* 改变数组的值
* @param b
*/
private static void changeArray(int[] b) {
b[0] = 20;
}
/**
* 改变对象的属性值
* @param student2
*/
private static void changeStudent(Student student2) {
student2.name = "zs";
}
}
11.构造方法
每一个类中都必须有构造方法,且至少有一个
(1)构造方法在程序中的调用方式是,new 类名(),类名()是构造方法,与成员方法相区分,对象.方法。
(2)在一个类中没有构造方法,程序中也会自动的生成一个默认的空构造方法,而成员方法必须创建才能调用。
(3)如果在一个类中定义了有参的构造方法,程序不会子动的生成默认的空构造方法,因此需要自己去定义一个默认的构造方法。
(4)构造方法的特征:public(修饰符) 没有返回类型 类名()
(5)构造方法的作用:创建对象,分配内存空间,给对象的属性赋初值,成员方法的作用是创建对象的行为。
(6)构造方法分为默认的构造方法(隐式的构造方法,两者型式一样),有参构造方法
如上面的第三点所述:
public class Student {
//类定义了属性和行为
//属性
String name;
int sno;
public Student() {//无参的构造方法
}
public Student(String name){//有参的构造方法
this.name = name;
}
}
package test_oop;
public class Test3 {
public static void main(String[] args) {
Student student = new Student("lisi");//给属性赋初值
System.out.println(student.name);//lisi
}
}
12.方法中的可变长参数
只能放在方法的参数的末尾,且一个方法只有一个可变长参数
package test_oop;
public class Test4 {
public static void main(String[] args) {
printStr(3,"hello");
printInt(3,5,6,7);
}
public static void printStr(int a,String s){//非可变长参数
for (int i = 0; i < a; i++) {
System.out.println(s);
//hello
//hello
//hello
}
}
public static void printInt(int a,int... b){//可变长参数本质上就是数组
for (int i = 0; i < a; i++) {
System.out.println(b[0]);
System.out.println(b[1]);
System.out.println(b[2]);
//5 6 7
}
}
}
13.This关键字
目的,区分成员变量和局部变量
package test_oop;
public class Car {
//成员变量
String brand;
double price;
public Car(){//构造方法也可以方法重载
this("大众");//调用当前类的有参构造 不能使用Car("大众")
System.out.println("无参构造");
}
public Car(String brand){
System.out.println("有参构造");
this.brand = brand;//调用当前类的属性
}
//非静态方法
public void sumPrice(int num){//返回值类型为void
System.out.println("汽车总价格为:"+num*price);
}
//静态方法
public void run(){
this.sumPrice(200000);//this.方法 调用当前类的方法
System.out.println("汽车在跑---");
}
public static void main(String[] args) {
Car car = new Car();//先调用Car() 在调用Car("大众")
//有参构造
// 无参构造
car.run();
//汽车总价格为:0.0
//汽车在跑---
}
}
14.类的方法重载(overload)
定义:在一个类中,具有二个或以上的同名方法,且方法的参数(个数,类型,顺序)不同,与返回值类型无关
package test_oop;
import java.sql.SQLOutput;
public class Test6 {
public static void main(String[] args) {
Test6 t = new Test6();
t.testMethod("1");
t.testMethod(2);
t.testMethod("第三个",3);
t.testMethod(4,"第四个");
}
public void testMethod(String s){
System.out.println("第一个");
}
public void testMethod(int a){
System.out.println("与第一个类型不同");
}
public void testMethod(String s,int a){
System.out.println(s+"与第一个数量不同");
}
public void testMethod(int a,String s){
System.out.println(s +"与第三个顺序不同" );
}
}
15.Package 包名
小写字母命名
命名方式:com.公司名.项目名.模块名
16.导包
使用Java.lang下的类不用导包
可以通过类名.方法/属性名,创建对象使用如Math.PI Math.abs(-3)等等
静态导包(不推荐,可读性差,不知道变量和方法的来源)
三者在类中的顺序
package test_oop;//1
import java.util.Scanner;//2
import static java.lang.Math.*;//静态导包不推荐
public class Test5 {//3
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);//导包 java.util 不导包可以使用java.util.Scanner
String name = sc.next();
System.out.println("sname:"+name);
System.out.println(PI);//不知道来源 *
System.out.println(Math.random());//使用Java.lang下的类不用导包
}
}