面向对象编程(基础部分)
类与对象
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 = 20
int 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();
}
}