【原】Java学习笔记015 - 面向对象
1 package cn.temptation; 2 3 public class Sample01 { 4 public static void main(String[] args) { 5 // 传递 值类型参数 和 传递 引用类型参数 6 int i = 2; 7 int j = 3; 8 System.out.println("方法调用前:i = " + i + ",j = " + j); 9 10 Calc calc = new Calc(); 11 int result = calc.add(i, j); 12 13 System.out.println("方法调用后:i = " + i + ",j = " + j); 14 15 // 这里的i 和 j 是main主函数中的局部变量,它们无法参与到对象的成员方法的运算中的,"井水不犯河水" 16 17 StudentTest studentTest = new StudentTest(); 18 // 在创建了StudentTest类的对象后,使用 对象名.成员方法()来进行调用,对于test这个成员方法,需要传入类型为Student类类型的实参,到底需要传入什么东西给它? 19 // 需要的是一个类类型的东西,可以传递一个类名称过去么? 答:不可以的,语法错误 20 // Student cannot be resolved to a variable 21 // studentTest.test(Student); 22 23 // 考虑到类是模板是抽象的东西,这里不需要抽象的类名称,而是需要传入一个具体的对象实例 24 Student student = new Student(); 25 System.out.println(student); 26 student.age = 18; 27 System.out.println("方法调用前,age = " + student.age); 28 29 // 依据类这个模板创建出来的对象自然应该是这个模板类的类型 30 studentTest.test(student); // 也就是传递了一个Student类类型的实例对象 31 32 System.out.println("方法调用后,age = " + student.age); 33 } 34 } 35 36 // 定义计算类 37 class Calc { 38 // 成员变量 39 40 // 成员方法 41 // 方法的形参是值类型 42 public int add(int i, int j) { 43 i *= 2; 44 j *= 3; 45 46 System.out.println("方法中:i = " + i + ",j = " + j); 47 48 return i + j; 49 } 50 } 51 52 // 定义学生类 53 class Student { 54 // 成员变量 55 int age; 56 57 // 成员方法 58 public void say() { 59 System.out.println("春眠不觉晓"); 60 } 61 } 62 63 // 定义学生类的测试类 64 class StudentTest { 65 // 成员方法 66 public void test(Student student) { 67 System.out.println(student); 68 // 67行打印出的内容 和 25行打印出的内容一致,其实就是告诉test方法,使用的形参student就是在内存中的堆上使用方法调用前通过new创建出来的那一块空间 69 student.age = 99; 70 } 71 } 72 73 /* 74 * 值类型、引用类型给方法传递的规则: 75 * 1、形参为值类型时:实参传递过来的是数据值,形参的改变对实参没有影响 76 * 2、形参为引用类型时:实参传递过来的是引用(地址,堆内存中的空间),形参的改变对实参会有影响 77 */
1 package cn.temptation; 2 3 public class Sample02 { 4 public static void main(String[] args) { 5 // 匿名数组 6 7 // Syntax error, insert "AssignmentOperator Expression" to complete Expression 8 // The left-hand side of an assignment must be a variable 9 // new int[] { 1, 2, 3 }; 10 // 上述写法有语法错误,因为匿名函数只能使用一次,考虑放在方法中作为实参来使用 11 12 // 对象的创建(类的实例化) 13 // Person person = new Person(); 14 // System.out.println(person); // cn.temptation.Person@15db9742 15 // person.say(); 16 17 // 匿名对象 18 // 下句没有语法错误,但是如何使用通过new关键字在堆中开辟出来的空间呢? 19 // new Person(); 20 // 下句把new Person()执行的结果作为实参传递给打印方法,打印出的结果说明new Person()这句话的确是创建出了一个匿名对象 21 // System.out.println(new Person()); // cn.temptation.Person@15db9742 22 23 // 匿名对象如何使用成员变量 和 成员方法? 24 // 我们已经知道的是 对象名.成员变量 和 对象名.成员方法,所以类推 匿名对象.成员变量 和 匿名对象.成员方法 25 // (new Person()).age = 18; 26 // 下句打印结果为0,为何? 27 // 答:上句使用new 关键字创建了一个匿名对象,下句使用了new 关键字又创建了一个匿名对象,自然使用的是其默认值 28 // System.out.println((new Person()).age); // 0 29 30 // 下面两句输出的结果没有区别,虽然是不同的匿名对象 31 // (new Person()).say(); 32 // (new Person()).say(); 33 34 // 匿名对象的优缺点: 35 // 优点:随时定义,随时使用 36 // 缺点:只能使用一次 37 } 38 } 39 40 //// 定义人类 41 //// 只写class关键字,不写类名去实现匿名类,语法错误 42 //// 语法错误:Syntax error on token "class", Identifier expected after this token 43 ////class { 44 //class Person { 45 // // 成员变量 46 // int age; 47 // 48 // // 成员方法 49 // public void say() { 50 // System.out.println("说话"); 51 // } 52 //}
1 package cn.temptation; 2 3 public class Sample03 { 4 public static void main(String[] args) { 5 // 成员变量的数据保护 6 7 Person person1 = new Person(); 8 person1.name = "张三"; 9 // 对age这个成员变量使用了private后,提示 The field Person.age is not visible 语法错误 10 // person1.age = 18; 11 person1.show(); 12 13 Person person2 = new Person(); 14 person2.name = "李四"; 15 // 直接拿着成员变量使用(赋值和取值),产生了不正常的错误数据 16 // 因为缺少对成员变量数据范围的检查 17 // 对age这个成员变量使用了private后,提示 The field Person.age is not visible 语法错误 18 // person2.age = 160; 19 person2.show(); 20 21 Person person3 = new Person(); 22 person3.name = "王五"; 23 person3.setAge(200); 24 person3.show(); 25 26 // 成员变量的数据保护的方案: 27 // 将成员变量设置为private,通过成员方法去访问它,来实现对成员变量的数据保护 28 } 29 } 30 31 class Person { 32 // 成员变量 33 // 对于不合理的数据,首先想的是在成员变量上做文章,考虑到成员变量能被随意的访问,所以会被随意的赋值 34 // 自然考虑如果不能被访问,自然也就不能被赋值,也就不会有不合理的数据 35 // 对于成员变量设置为不能访问,Java中提供了一个关键字 private 私有的 36 String name; 37 // int age; 38 private int age; // 给成员变量加上private关键字,它不能被访问了,但是这不是我们想要的最终结果 39 40 // 因为成员变量不加private,就可以随意赋值,加了private又无法访问,这里就需要考虑结合其他的途径 41 // 考虑到还要使用这个特征age,如果给age进行赋值时有相应的检查就好了,显然不是一句语句可以完成,既然是需要多个语句来做这个事情 42 // 自然有想到要使用多个语句的封装形式-----方法,使用方法对赋值进行检查 43 // 同时观察到要制作的这个检查方法是和成员变量在同一个类中的方法,即成员变量使用了private修饰符,在这个检查方法中也可以访问到 44 45 // 成员方法 46 public void setAge(int personAge) { 47 if (personAge < 0 || personAge > 120) { 48 System.out.println("设置的年龄不正确!!!"); 49 } else { 50 age = personAge; 51 } 52 } 53 54 public void show() { 55 System.out.println("姓名为:" + name + ",年龄为:" + age); 56 } 57 }
1 package cn.temptation; 2 3 public class Sample04 { 4 public static void main(String[] args) { 5 // private 关键字的用法 6 7 Man man = new Man(); 8 man.name = "王五"; 9 // 语法错误:The field Man.age is not visible 10 // man.age = 28; 11 12 man.show1(); 13 14 // 使用private修饰的成员变量无法访问 15 // 语法错误:The method show2() from the type Man is not visible 16 // man.show2(); 17 18 man.show3(); 19 20 // 语法错误:The method show4() from the type Man is not visible 21 // man.show4(); 22 } 23 } 24 25 // 定义一个Man类 26 class Man { 27 // 成员变量 28 String name; 29 // 成员变量age没有使用默认值,给其赋值为18 30 private int age = 18; 31 32 // 成员方法 33 public void show1() { 34 System.out.println("这是public修饰的show1方法"); 35 } 36 37 private void show2() { 38 System.out.println("这是private修饰的show2方法"); 39 } 40 41 public void show3() { 42 // private修饰的成员变量age在本类的成员方法中可以被访问到,不论本类的成员方法是public修饰的,还是private修饰的 43 System.out.println(age); 44 } 45 46 private void show4() { 47 // private修饰的成员变量age在本类的成员方法中可以被访问到,不论本类的成员方法是public修饰的,还是private修饰的 48 System.out.println(age); 49 } 50 }
1 package cn.temptation; 2 3 public class Sample05 { 4 public static void main(String[] args) { 5 // 通过制作setXXX(...)实现对成员变量进行赋值操作 6 // 通过制作getXXX(...)实现对成员变量进行取值操作 7 8 Animal animal = new Animal(); 9 animal.setName("狗"); 10 animal.setWeight(10); 11 12 System.out.println("名称为:" + animal.getName() + ",体重为:" + animal.getWeight()); 13 } 14 } 15 16 // 定义动物类 17 class Animal { 18 // 成员变量 19 // 名称 20 private String name; 21 // 体重 22 private int weight; 23 24 // 成员方法 25 public void setName(String animalName) { 26 // 通过形参从外部接收到数据,把数据赋值给设置为private的成员变量 27 name = animalName; 28 } 29 30 public String getName() { 31 return name; 32 } 33 34 public void setWeight(int animalWeight) { 35 // 通过形参从外部接收到数据,把数据赋值给设置为private的成员变量 36 weight = animalWeight; 37 } 38 39 public int getWeight() { 40 return weight; 41 } 42 }
1 package cn.temptation; 2 3 public class Sample06 { 4 public static void main(String[] args) { 5 // // 需求:定义一个手机类,三个成员变量品牌brand,价格price,颜色color,使用成员变量数据保护 6 // Phone phone = new Phone(); 7 // phone.setBrand("iphone 7"); 8 // phone.setPrice(5888); 9 // phone.setColor("白色"); 10 // 11 // System.out.println("手机品牌为:" + phone.getBrand() + ",价格为:" + phone.getPrice() + ",颜色为:" + phone.getColor()); 12 } 13 } 14 15 //// 定义手机类 16 //class Phone { 17 // // 成员变量 18 // // 品牌 19 // private String brand; 20 // // 价格 21 // private int price; 22 // // 颜色color 23 // private String color; 24 // 25 // // 成员方法 26 // public void setBrand(String param) { 27 // brand = param; 28 // } 29 // 30 // public String getBrand() { 31 // return brand; 32 // } 33 // 34 // public void setPrice(int param) { 35 // price = param; 36 // } 37 // 38 // public int getPrice() { 39 // return price; 40 // } 41 // 42 // public void setColor(String param) { 43 // color = param; 44 // } 45 // 46 // public String getColor() { 47 // return color; 48 // } 49 //}
1 package cn.temptation; 2 3 public class Sample07 { 4 public static void main(String[] args) { 5 // 思考一下创建对象这一步,通过类的实例化 6 // 观察一下new这一部分,new关键字后面写的是一个带有小括号的东西,这个小括号让我们联想到了方法(函数) 7 // 1、从形式来看,创建对象好像是从new一个方法得到的 8 // 2、这个写在new后面的方法在类中没有看到 9 10 // 这个方法称为 Java中的 构造方法(构造函数) 11 12 // 构造函数定义:用来创建对象时使用的方法 13 // 类中可以不写构造函数,由JDK自动生成出构造函数 14 // 通过使用XJad反编译工具对.class字节码文件进行反编译,查看一下JDK的确自动生成了构造函数 15 Girl girl = new Girl(); 16 17 // 注意:有几个类,对应就有几个.class文件,在定义类时,eclipse就自动为我们生成了对应的.class文件 18 } 19 } 20 21 //定义妹纸类 22 class Girl { 23 // 成员变量 24 private String name; 25 26 // 成员方法 27 public void setName(String girlName) { 28 name = girlName; 29 } 30 31 public String getName() { 32 return name; 33 } 34 }
1 package cn.temptation; 2 3 public class Sample08 { 4 public static void main(String[] args) { 5 // JDK生成出来的构造函数的特点: 6 // 1、无修饰符 7 // 2、无返回值类型,也没有返回值 8 // 3、无参数 9 // 4、方法名和类名一致 10 11 // 手写一个构造函数 12 // 1、手写一个构造函数,JDK不再为类自动生成构造函数 13 // 2、创建对象时,执行了写在构造函数中的语句 14 // 3、构造函数比所有的成员方法都要先执行,理解:小鸟还在蛋里,就要它飞行,不现实 15 Bird bird = new Bird(); 16 bird.say(); 17 } 18 } 19 20 class Bird { 21 // 成员变量 22 23 // 构造函数 24 // 不使用修饰符修饰的构造函数 25 Bird() { 26 System.out.println("我是Bird的构造函数"); 27 } 28 29 // 使用public可以修饰构造函数 30 // public Bird() { 31 // System.out.println("我是Bird的构造函数"); 32 // } 33 34 // 使用private也可以修饰构造函数,但是使用private修饰后,进行类的实例化时出现语法错误:The constructor Bird() is not visible 35 // private Bird() { 36 // System.out.println("我是Bird的构造函数"); 37 // } 38 39 // 成员方法 40 public void say() { 41 System.out.println("这是成员方法say"); 42 } 43 }
1 package cn.temptation; 2 3 public class Sample09 { 4 public static void main(String[] args) { 5 // 思考这样的场景:对于小孩子被生出来,正常情况就有两个手、两个脚 6 7 // 下面写法:创建出Baby对象,再使用setXXX方法进行赋值,这样的写法对使用者有要求,创建出对象后不能忘记使用setXXX方法 8 Baby baby1 = new Baby(); 9 baby1.setHands(2); 10 baby1.setLegs(2); 11 System.out.println("手为:" + baby1.getHands() + "只,脚为:" + baby1.getLegs() + "只"); 12 13 // 考虑在创建对象时就应该初始化赋值,自然考虑在构造函数上做处理 14 // 可以根据开发人员的需要,制作多种多样的构造函数的重载方法 15 Baby baby2= new Baby(2, 2); 16 System.out.println("手为:" + baby2.getHands() + "只,脚为:" + baby2.getLegs() + "只"); 17 18 // 注意: 19 // 1、没有有参构造函数,也没有无参构造函数,那么JDK会自动生成无参构造函数 20 // 2、编写有参构造函数,不写无参构造函数,那么那些使用了无参构造函数创建兑现搞得语句就会有语法错误The constructor Baby() is undefined 21 // 反编译字节码文件,发现此时JDK是不会自动生成无参构造函数 22 // 大家使用构造函数时,建议把无参构造函数都手写补上 23 } 24 } 25 26 // 小孩子类 27 class Baby { 28 // 成员变量 29 private int hands; 30 private int legs; 31 32 // 构造函数(无参) 33 public Baby() { 34 System.out.println("这是Baby的无参构造函数"); 35 } 36 37 // 构造函数(有参) 38 public Baby(int babyHands, int babyLegs) { 39 System.out.println("这是Baby的有参构造函数"); 40 hands = babyHands; 41 legs = babyLegs; 42 } 43 44 // 成员方法 45 public void setHands(int babyHands) { 46 hands = babyHands; 47 } 48 49 public int getHands() { 50 return hands; 51 } 52 53 public void setLegs(int babyLegs) { 54 legs = babyLegs; 55 } 56 57 public int getLegs() { 58 return legs; 59 } 60 }
1 package cn.temptation; 2 3 public class Sample10 { 4 public static void main(String[] args) { 5 // 需求:创建手机类,有品牌、价格、颜色,默认出厂标识码(pinCode),使用private成员变量、构造函数、set方法、get方法 6 Phone phone = new Phone("xiaomi", 1200, "白色", "A123456"); 7 phone.show(); 8 } 9 } 10 11 // 定义手机类 12 class Phone { 13 // 成员变量 14 // 品牌 15 private String brand; 16 // 价格 17 private int price; 18 // 颜色color 19 private String color; 20 // 出厂标识码 21 private String pinCode; 22 23 // 构造函数(无参) 24 public Phone() { 25 System.out.println("这是无参构造函数"); 26 } 27 28 // 构造函数(有参) 29 public Phone(String phoneBrand, int phonePrice, String phoneColor, String phonePinCode) { 30 brand = phoneBrand; 31 price = phonePrice; 32 color = phoneColor; 33 pinCode = phonePinCode; 34 } 35 36 // 成员方法 37 public void setBrand(String param) { 38 brand = param; 39 } 40 41 public String getBrand() { 42 return brand; 43 } 44 45 public void setPrice(int param) { 46 price = param; 47 } 48 49 public int getPrice() { 50 return price; 51 } 52 53 public void setColor(String param) { 54 color = param; 55 } 56 57 public String getColor() { 58 return color; 59 } 60 61 public void setPinCode(String param) { 62 pinCode = param; 63 } 64 65 public String getPinCode() { 66 return pinCode; 67 } 68 69 // 自定义的成员方法 70 public void show() { 71 System.out.println("品牌为:" + brand + ",价格为:" + price + ",颜色为:" + color + ",出厂标识码为:" + pinCode); 72 } 73 }