面向对象编程(基础部分)
类与对象
01:
public class ObjectWorkDemo
{public static void main(String[] args){Cat cat1 = new Cat();cat1.name = "Tom";cat1.age = 3;cat1.color = "white";Cat cat2 = new Cat();cat2.name = "xiaohua";cat2.age = 100;cat2.color = "flower";}
}class Cat
{String name;int age;String color;
}
对象内存布局
属性/成员变量
注意事项和细节说明
01:
public class PropertiesDetail
{public static void main(String[] args){Person p1 = new Person();//p1 对象引用 Person() 才是真正的数据空间(真正的对象)}
}class Person
{int age;String name;double sal;boolean isPass;
}
创建对象
创建过程
小练习
成员方法
public class PersonWorkDemo
{public static void main(String [] args){Person p1 = new Person();p1.speak();p1.cal01();p1.cal02(5);int res = p1.getSum(10,5);System.out.println(res);}
}class Person{String name;int age;public void speak(){System.out.println("I am good person");}public void cal01(){int res = 0;for (int i = 1;i<=1000;i++){res+=i;}System.out.println(res);}public void cal02(int n){int res = 0;for (int i = 1;i<=n;i++){res+=i;}System.out.println(res);}public int getSum(int a,int b){return a+b;}}
方法调用机制
成员方法的好处
-
提高代码的复用性
-
可以将实现的细节封装起来,然后供其他用户来调用即可
成员方法的定义
注意事项和使用细节
小练习
01:
public class TestWork
{public static void main(String [] args){AA a = new AA();boolean b = a.isOdd(1);if (b) System.out.println("yes");else System.out.println("no");}
}class AA
{public boolean isOdd(int num){if num%2!=0?true:false;}public void print(int row,int col,char c){for (int i = 0;i<row;i++){for (int j = 0;j<col;j++){System.out.print(c);}System.out.println();}}
}
成员方法传参机制
- 基本数据类型,传递的是值(值拷贝),形参的任何改变不影响实参
01:
public class MethodParameter01
{public static void main(String[] args){int a = 10;int b = 20;AA object = new AA();object.swap(a,b);System.out.println("a = "+a+" b = "+b);//a = 10 b = 20}
}class AA
{public void swap(int a,int b){System.out.println("a = "+a+" b = "+b);//a = 10 b = 20int tmp = a;a = b;b = tmp;System.out.println("Later a = "+a+" b = "+b);//a = 20 b = 10}
}
- 引用类型传递的是地址(传递也是值,但是值是地址),可以通过形参影响实参
02:
public class MethodParameter02
{public static void main(String[] args){B b = new B(); int [] arr = {1,2,3};b.test100(arr);System.out.println("main:");for (int i = 0;i<arr.length;i++){System.out.print(arr[i]+"\t");//200 2 3}System.out.println();Person p = new Person();p.name = "Tom";p.age = 10;b.test200(p);System.out.println("main age = "+p.age);//1000}
}class Person
{String name;int age;
}class B
{public void test200(Person p){p.age = 1000;}public void test100(int [] arr){arr[0] = 200;for (int i = 0;i<arr.length;i++){System.out.print(arr[i]+"\t");//200 2 3}System.out.println();}
}
这里的"tom"p会被当做垃圾销毁掉
小练习
public class TestDemo
{public static void main(String[] args){Person p = new Person();p.name = "Jack";p.age = 30;MyTools myT = new MyTools();Person p2 = myT.copyPerson(p);System.out.println(p==p2);//false}
}class Person
{String name;int age;
}class MyTools
{public Person copyPerson (Person p){Person p2 = new Person();p2.name = p.name;p2.age = p.age;return p2;}
}
如果此时修改p2.name,并不会改变p.name,p2.name会指向一个新地址
方法递归调用
递归举例
01:
public class Recursion01
{public static void main(String [] args){T t1 = new T();t1.test(4);}
}class T
{public void test(int n){if (n>2){test(n-1);}System.out.println("n = "+n);}
}//n = 2
//n = 3
//n = 4
02:
public class Recursion01
{public static void main(String [] args){T t1 = new T();t1.test(4);}
}class T
{public void test(int n){if (n>2){test(n-1);}else{System.out.println("n = "+n);}}
}//n = 2
03:
public class Recursion01
{public static void main(String [] args){T t1 = new T();int res = t1.factorial(5);System.out.println(res);//120}
}class T
{public int factorial(int n){if (n==1){return 1;}else{return factorial(n-1)*n;}}
}
递归重要规则
小练习
01:
class T
{public int fab(int n){if (n>=1){if (n==1 || n==2){return 1;}else{return fab(n-1)+fab(n-2);}}else{System.out.println("Input Error");return -1;}}
}
02:
class T
{public int peach(int day){if (day==10){return 1;}else if (day >= 1 && day <= 9){return (peach(day+1)+1)*2;}else{System.out.println("day在1-10");return -1;}}
}
老鼠出迷宫
03:
略!
汉诺塔
八皇后
略!
方法重载
案例
01:
class MyCalculator
{public int calculate(int n1,int n2){return n1+n2;}public double calculate(int n1,double n2){return n1+n2;}public double calculate(double n2,int n1){return n1+n2;}public int calculate(double n1,int n2,int n3){return n1+n2+n3;}
}
注意事项和使用细节
小练习
01:
01:
public class Test
{public static void main(String[] args){Methods obj = new Methods();obj.m(8);obj.m(8,6);obj.m("dadas");}
}class Methods
{public void m(int n){System.out.println(n*n);}public void m(int n1,int n2){System.out.println(n1*n2);}public void m(String str){System.out.println(str);}
}
02:
public class Test
{public static void main(String[] args){Methods obj = new Methods();}
}class Methods
{public int findMax(int n1,int n2){return n1>n2?n1:n2;}public double findMax(double n1,double n2){return n1>n2?n1:n2;}public double findMax(double n1,double n2,double n3){double max1 = n1>n2?n1:n2;double max2 = max1>n3?max1:n3;return max2;}
}
可变参数
案例
01:
public VariableParameter01
{public static void main(String[] args){HspMethod obj = new HspMethod;int res = obj.sum(1,5,100);System.out.println(res);//106}
}class HspMethod
{public int sum(int... nums){int sum =0 ;for (int i = 0;i<nums.length;i++){sum+=nums[i];}return sum;}
}
注意事项和使用细节
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5wXf9jxM-1634262458757)(C:\Users\Tom\AppData\Roaming\Typora\typora-user-images\image-20210912133042199.png)]
- 可变参数的实参可以为数组
01:
public class VariableParameterDetail
{public static void(String[] args){int[] arr = {1,2,3};T t1 = new T();t1.f1(arr);}
}class T
{public void f1(int... nums){System.out.println(nums.length);//3}
}
- 可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
01:
class T
{public void f2(double str,double...nums){}
}
- 一个形参列表中只能出现一个可变参数
public int sum(String str,int... nums01,String... nums02);//Error
小练习
01:
public class HspMethod
{public String showScore(String name,double... scores){double totalScore = 0;for (int i = 0;i<scores.length;i++){totalScore+=scores[i];}return name+scores.length+totalScore;}
}
作用域
注意事项和使用细节
- 属性和局部变量可以重名,访问时遵循就近原则
01:
public class ScopeDemo
{public static void main(String[] args){}
}class Person
{String name = "Tom";public void say(){String name = "king";System.out.println("say() name = "+name);//say() name = king}
}
02:
public class ScopeDemo
{public static void main(String[] args){}
}class Person
{String name = "Tom";public void say(){// String name = "king";System.out.println("say() name = "+name);//say() name = Tom}
}
- 在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名
01:
public class ScopeDemo
{public static void main(String[] args){}
}class Person
{String address = "beijin";//String address = "guanzhou";//Error 重复定义String name = "hsp";}
01:
public class ScopeDemo
{public static void main(String[] args){Person p1 = new Person();p1.say();//当执行say()方法时,say方法的局部变量比如name会创建,当say执行完毕后,name局部变量销毁,但是属性(全局变量)仍然可以使用}
}class Person
{String name = "Tom";public void say(){String name = "king";System.out.println("say() name = "+name);}
}
- 作用域范围不同
class T
{public void test(){Person p1 = new Person();System.out.println(p1.name);}public void test02(Person p){System.out.println(p.name);}
}class Person
{String name = "jack";
}
构造方法/构造器
- 案例
01:
public class Constructor01
{public static void main(String[] args){Person p1 = new Person("jack",80);System.out.println(p1.name+" "+p1.age);}
}class Person
{String name;int age;public Person(String pName,int pAge){name = pName;age = pAge;}
}
注意事项和使用细节
小练习
01:
public class Constructor01
{public static void main(String[] args){}
}class Person
{String name;int age;public Person(){age = 18;}public Person(String pName,int pAge){name = pName;age = pAge;}
}
对象创建的流程分析
javap
- P243
this关键字
01:
public class This01
{public static void main(String[] args){Dog dog1 = new Dog("大壮",3);dog1.info();}
}class Dog
{String name;int age;// public Dog(String dName,int dAge)// {// name = dName;// age = dAge;// }public Dog(String name,int age){this.name = name;this.age = age;}public void info(){System.out.println(name+" "+age+" ");}
}
public class This01
{public static void main(String[] args){Dog dog1 = new Dog("大壮",3);System.out.println("dog1的hashcode = "+dog1.hashCode());dog1.info();Dog dog2 = new Dog("小东",7);System.out.println("dog1的hashcode = "+dog2.hashCode());dog2.info();}
}class Dog
{String name;int age;// public Dog(String dName,int dAge)// {// name = dName;// age = dAge;// }public Dog(String name,int age){this.name = name;this.age = age;System.out.println("this.hashCode = "+this.hashCode());}public void info(){System.out.println(name+" "+age+" ");}
}
this使用细节
01:
class T
{public void f1(){System.out.println("f1ok");}public void f2(){System.out.println("f2ok");f1();this.f1();}
}
02:
class T
{public T(){this("jack",100);System.out.println("T() 构造器");//在这里访问T(String name,int age)//this("jack",100);//ERROR 注意:如果有this(参数列表);必须放在第一条语句}public T(String name,int age){System.out.println("T(String name,int age)构造器");}}
案例
01:
public class TestPerson
{public static void main(String[] args){}
}class Person
{String name;int age;public Person(String name,int age){this.name = name;this.age = age;}public boolean compareTo(Person p){return this.name.equals(p.name) && this.age==p.age;}
});System.out.println("dog1的hashcode = "+dog2.hashCode());dog2.info();}
}