【原】Java学习笔记020 - 面向对象
1 package cn.temptation; 2 3 public class Sample01 { 4 public static void main(String[] args) { 5 // 成员方法的参数列表: 6 // 1、参数列表中的数据类型是值类型 7 // 2、参数列表中的数据类型是引用类型 8 // A:一般的类:成员方法使用的该类的对象 9 10 Person person = new Person(); 11 person.method(123); 12 13 TestPerson testPerson = new TestPerson(); 14 Person personEx = new Person(); 15 testPerson.test(personEx); 16 17 // 使用匿名对象作为方法的实参进行传递 18 testPerson.test(new Person()); 19 } 20 } 21 22 class Person { 23 // 成员方法 24 public void method(int i) { 25 System.out.println("i的值为:" + i); 26 } 27 } 28 29 class TestPerson { 30 // 成员方法 31 public void test(Person person) { 32 person.method(999); 33 } 34 }
1 package cn.temptation; 2 3 public class Sample02 { 4 public static void main(String[] args) { 5 // 成员方法的参数列表: 6 // 1、参数列表中的数据类型是值类型 7 // 2、参数列表中的数据类型是引用类型 8 // B:抽象类:成员方法使用的是该抽象类的具体实现子类的对象 9 10 TestAnimal testAnimal = new TestAnimal(); 11 12 // 语法错误:Cannot instantiate the type Animal 13 // testAnimal.test(new Animal()); 14 15 // 多态 16 Animal animal = new Dog(); 17 testAnimal.test(animal); 18 19 // 使用匿名对象作为实参进行传递 20 // 下面两句均正确 21 testAnimal.test(new Dog()); 22 testAnimal.test((Animal)(new Dog())); 23 24 Dog dog = new Dog(); 25 testAnimal.test(dog); 26 testAnimal.testEx(dog); 27 // The method testEx(Dog) in the type TestAnimal is not applicable for the arguments (Animal) 28 // testAnimal.testEx(animal); 29 30 // 注意: 31 // 1、继承关系中的子类类型出现在父类对象出现的场合,可以代替父类对象 32 // 2、继承关系中的父类类型出现在子类对象出现的场合,不可以代替子类对象 33 } 34 } 35 36 // 抽象类 37 abstract class Animal { 38 public abstract void eat(); 39 } 40 41 // 具体实现子类 42 class Dog extends Animal { 43 @Override 44 public void eat() { 45 System.out.println("狗吃肉"); 46 } 47 } 48 49 class TestAnimal { 50 // 成员方法 51 public void test(Animal animal) { 52 animal.eat(); 53 } 54 55 public void testEx(Dog dog) { 56 dog.eat(); 57 } 58 }
1 package cn.temptation; 2 3 public class Sample03 { 4 public static void main(String[] args) { 5 // 成员方法的参数列表: 6 // 1、参数列表中的数据类型是值类型 7 // 2、参数列表中的数据类型是引用类型 8 // C:接口:成员方法使用的是该接口的实现类的对象 9 10 TestSport testSport = new TestSport(); 11 // 语法错误:Cannot instantiate the type Sport 12 // testSport.test(new Sport()); 13 14 // 多态 15 Sport sport = new Sporter(); 16 testSport.test(sport); 17 18 // 使用匿名对象作为实参进行传递 19 testSport.test(new Sporter()); 20 } 21 } 22 23 interface Sport { 24 public abstract void swim(); 25 } 26 27 class Sporter implements Sport { 28 @Override 29 public void swim() { 30 System.out.println("学会了游泳"); 31 } 32 } 33 34 class TestSport { 35 public void test(Sport sport) { 36 sport.swim(); 37 } 38 }
1 package cn.temptation; 2 3 public class Sample04 { 4 public static void main(String[] args) { 5 // 成员方法的返回值类型: 6 // 1、返回值的数据类型是值类型 7 // 2、返回值的数据类型是引用类型 8 // A:一般的类:返回的是该类的对象 9 10 Man man = new Man(); 11 double income = man.income(10000); 12 13 TestMan testMan = new TestMan(); 14 System.out.println(testMan.test()); 15 } 16 } 17 18 class Man { 19 public double income(int money) { 20 System.out.println("赚了钱要上交"); 21 return money * 0.9; 22 } 23 } 24 25 class TestMan { 26 public Man test() { 27 // 返回引用数据类型的默认值null 28 // return null; 29 30 // 返回Man类类型的对象 31 // Man man = new Man(); 32 // return man; 33 34 // 返回匿名对象 35 // return (new Man()); 36 return new Man(); 37 } 38 }
1 package cn.temptation; 2 3 public class Sample05 { 4 public static void main(String[] args) { 5 // 成员方法的返回值类型: 6 // 1、返回值的数据类型是值类型 7 // 2、返回值的数据类型是引用类型 8 // B:抽象类:返回的是该抽象类的具体实现子类的对象 9 10 TestHuman testHuman = new TestHuman(); 11 Human human = testHuman.test(); 12 human.live(); 13 } 14 } 15 16 abstract class Human { 17 public abstract void live(); 18 } 19 20 class Chinese extends Human { 21 @Override 22 public void live() { 23 System.out.println("天朝的人过着苦逼的生活"); 24 } 25 } 26 27 class TestHuman { 28 public Human test() { 29 // 抽象类不能实例化 30 // Human human = new Human(); 31 // return human; 32 33 // 多态 34 // Human human = new Chinese(); 35 // return human; 36 37 // 返回匿名对象 38 // return (new Chinese()); 39 return new Chinese(); 40 } 41 }
1 package cn.temptation; 2 3 public class Sample06 { 4 public static void main(String[] args) { 5 // 成员方法的返回值类型: 6 // 1、返回值的数据类型是值类型 7 // 2、返回值的数据类型是引用类型 8 // C:接口:返回的是该抽象类的具体实现子类的对象 9 10 TestAbility testAbility = new TestAbility(); 11 Ability ability = testAbility.test(); 12 ability.fly(); 13 } 14 } 15 16 interface Ability { 17 public abstract void fly(); 18 } 19 20 class Phoenix implements Ability { 21 @Override 22 public void fly() { 23 System.out.println("凤凰会飞"); 24 } 25 } 26 27 class TestAbility { 28 public Ability test() { 29 // 接口不能实例化 30 // Ability ability = new Ability(); 31 // return ability; 32 33 // 多态 34 // Ability ability = new Phoenix(); 35 // return ability; 36 37 // 匿名接口的实现类对象 38 // return (new Phoenix()); 39 return new Phoenix(); 40 } 41 }
1 package cn.temptation; 2 3 public class Sample07 { 4 public static void main(String[] args) { 5 TestGirl testGirl = new TestGirl(); 6 // Girl girl = testGirl.test(); 7 // girl.show(); 8 9 // 链式编程写法:调用某一个成员方法,获得的是一个对象,自然就可以再使用这个对象的成员方法 10 testGirl.test().show(); 11 12 // 链式编程写法结合匿名对象的使用 13 (new TestGirl()).test().show(); 14 15 // 链式编程写法 和 匿名对象写法的区别: 16 // 1、链式编程写法:调用的都是方法;匿名对象写法需要new 某一个类的构造函数来获取该类的实例对象 17 // 2、链式编程写法通过方法的调用得到一个对象,再使用该对象的成员方法,最终使用的是一个对象的成员方法;匿名对象获取到的是一个对象 18 } 19 } 20 21 class Girl { 22 public void show() { 23 System.out.println("妹纸负责貌美如花"); 24 } 25 } 26 27 class TestGirl { 28 public Girl test() { 29 return new Girl(); 30 } 31 }
1 package cn.temptation; 2 3 public class Sample08 { 4 public static void main(String[] args) { 5 // Student student1 = new Student(); 6 // Student student2 = new Student(); 7 8 // 对于上述的代码的写法,我们清楚的知道,对象的创建都是有资源的消耗的(堆内存中开辟了空间) 9 // 当这些对象不再使用时,需要被销毁,Java中不需要开发人员进行手工销毁,提供了对不再使用的对象自动销毁的机制,称为垃圾回收机制(GC:Garbage Collection) 10 // 这个GC并不是实时进行的,而是要等到垃圾回收器空闲时才会来进行销毁,所以可以看出,在程序中漫无目的的创建对象对程序的性能有影响 11 // 所以,也就考虑在程序中,只需要使用一个对象时,就创建一个对象并在程序执行的过程中就保持只有一个对象 12 13 // "单个实例对象问题"在软件开发的过程中是一个常见的问题,也曾经困扰过开发人员,在长期的软件开发过程中,开发人员针对这些有代表性的问题积累了解决这些问题的经验 14 // 对这些经验的归纳总结,形成了大家都认可的设计方案,称为"设计模式"(Design Pattern) 15 16 // 设计模式常见的有23种,大家对于设计模式的理解和掌握希望遵循这样的原则:不要为了使用设计模式而使用设计模式 17 // 好的程序、好的代码都是反复迭代出来的,没有一蹴而就的;只有更适合业务的设计,没有最通用的设计 18 19 // 【单例模式】:Singleton,保证程序执行过程中有且仅有一个对象(单例) 20 21 // 【单例模式的实现方式1、饿汉式】:伴随着类的加载,就进行类的实例化,创建出该类的对象出来 22 23 // 随意new出对象的方式 24 // Singleton singleton1 = new Singleton(); 25 // Singleton singleton2 = new Singleton(); 26 27 // System.out.println("singleton1:" + singleton1); 28 // System.out.println("singleton2:" + singleton2); 29 30 // 第2次迭代写法的调用 31 // Singleton singleton1 = Singleton.getInstance(); 32 // Singleton singleton2 = Singleton.getInstance(); 33 34 // System.out.println("singleton1:" + singleton1); 35 // System.out.println("singleton2:" + singleton2); 36 37 // 第3次迭代写法的调用 38 // System.out.println(Singleton.instance); 39 // System.out.println(Singleton.instance); 40 41 // 第4次迭代写法的调用 42 // Singleton singleton1 = Singleton.getInstance(); 43 // Singleton singleton2 = Singleton.getInstance(); 44 // System.out.println("singleton1:" + singleton1); 45 // System.out.println("singleton2:" + singleton2); 46 } 47 } 48 49 // 学生类 50 //class Student { 51 // 52 //} 53 54 //class Singleton { 55 // // 成员变量 56 // // 【第3次迭代】从静态的成员得到启示,考虑使用static关键字的成员都是伴随着类的加载而加载的,且只执行一次 57 // // 这样写,效果上达到了执行过程中只有单个实例对象,但是使用public暴露静态的成员变量给外部使用不太好 58 //// public static Singleton instance = new Singleton(); 59 // 60 // // 【第4次迭代】 61 // private static Singleton instance = new Singleton(); 62 // 63 // // 构造函数 64 // // 【第1次迭代】构造函数设置为private,让随意new成为不可能 65 // private Singleton() { 66 // 67 // } 68 // 69 // // 成员方法 70 // // 【第1次迭代】构造函数设置为private不能new出对象,类似于类中的成员变量的数据保护处理方式,考虑创建一个外部可以访问的方法来获取Singleton类类型的对象 71 //// public Singleton getInstance() { 72 //// // 考虑到在Singleton类的外部无法访问private修饰的构造函数,但是在类的成员方法中还是可以访问 73 //// Singleton singleton = new Singleton(); 74 //// return singleton; 75 //// } 76 // 77 // // 【第2次迭代】让外部可以调用到获取实例的方法,像第1次迭代里写的必须要使用对象名.成员方法才是使用,但是对象都创建不出来,怎么获取对象名呢? 78 // // 让外部可以调用到获取实例的方法,应该通过类名.成员方法才合适 79 // // 但是这样写还是有问题的,因为在成员方法的内部每次方法被调用,都会创建出一个新的Singleton类型的对象返回 80 //// public static Singleton getInstance() { 81 //// Singleton singleton = new Singleton(); 82 //// return singleton; 83 //// } 84 // 85 // // 【第4次迭代】 86 // public static Singleton getInstance() { 87 // return instance; 88 // } 89 //}
1 package cn.temptation; 2 3 public class Sample09 { 4 public static void main(String[] args) { 5 // 【单例模式的实现方式2、懒汉式】:第一次使用类的对象时,才进行类的实例化,后续都是使用第一次创建出来的对象实例 6 Singleton singleton1 = Singleton.getInstance(); 7 System.out.println("singleton1:" + singleton1); 8 9 Singleton singleton2 = Singleton.getInstance(); 10 System.out.println("singleton2:" + singleton2); 11 } 12 } 13 14 class Singleton { 15 // 成员变量 16 // 懒汉式不需要随着类的加载就创建类的实例对象,所以只定义成员变量不做初始化操作 17 private static Singleton instance; 18 19 // 构造函数 20 // 构造函数设置为private,让随意new成为不可能 21 private Singleton() { 22 23 } 24 25 // 成员方法 26 public static Singleton getInstance() { 27 if (instance == null) { // 说明当前程序中没有Singleton类类型的对象 28 // 因为类加载时没有立即创建该类的对象,所以第一次调用getInstance方法创建该类的对象时,这个静态变量instance的值为默认值null 29 // 第一次创建该类的对象时需要进行类的初始化 30 instance = new Singleton(); 31 } 32 33 // 后续使用时,都是使用第一次创建出来的对象实例 34 return instance; 35 } 36 }
1 package cn.temptation; 2 3 public class Sample10 { 4 public static void main(String[] args) { 5 // 设计模式中的模板方法模式(Template Method) 6 Shape shape1 = new Matrix(2, 3); 7 shape1.print(); 8 9 Shape shape2 = new Circle(4); 10 shape2.print(); 11 } 12 } 13 14 // 抽象类:形状 15 abstract class Shape { 16 // 思考:为什么没有定义成员变量? 17 // 答:因为计算不同的形状需要的参数是不同的,在抽象类中不定死成员方法的参数列表,而让各个继承的具体实现子类自由设置 18 19 // 成员变量 20 21 // 构造函数 22 23 // 成员方法 24 // 抽象的成员方法:求面积 25 public abstract double getArea(); 26 27 // 抽象的成员方法:求周长 28 public abstract double getLength(); 29 30 // 非抽象的成员方法:提供一个打印方法 31 public void print() { 32 System.out.println("面积为:" + getArea() + ",周长为:" + getLength()); 33 } 34 } 35 36 // 具体实现子类:矩形 37 class Matrix extends Shape { 38 // 成员变量 39 // 长 40 private int i; 41 // 宽 42 private int j; 43 44 // 构造函数 45 public Matrix() { 46 47 } 48 49 public Matrix(int i, int j) { 50 super(); 51 this.i = i; 52 this.j = j; 53 } 54 55 // 成员方法 56 public int getI() { 57 return i; 58 } 59 60 public void setI(int i) { 61 this.i = i; 62 } 63 64 public int getJ() { 65 return j; 66 } 67 68 public void setJ(int j) { 69 this.j = j; 70 } 71 72 // 自定义的成员方法(重写) 73 @Override 74 public double getArea() { 75 return this.i * this.j; 76 } 77 78 @Override 79 public double getLength() { 80 return 2 * (this.i + this.j); 81 } 82 } 83 84 // 具体实现子类:圆形 85 class Circle extends Shape { 86 // 成员变量 87 // 半径 88 private int k; 89 90 // 构造函数 91 public Circle() { 92 super(); 93 } 94 95 public Circle(int k) { 96 super(); 97 this.k = k; 98 } 99 100 // 成员方法 101 public int getK() { 102 return k; 103 } 104 105 public void setK(int k) { 106 this.k = k; 107 } 108 109 // 自定义的成员方法(重写) 110 @Override 111 public double getArea() { 112 return Math.PI * this.k * this.k; 113 } 114 115 @Override 116 public double getLength() { 117 return 2 * Math.PI * this.k; 118 } 119 }
1 package cn.temptation; 2 3 public class Sample11 { 4 public static void main(String[] args) { 5 /* 6 * 权限修饰符的总结: 7 * |(同一包下)当前类(本类) | (同一包下)子类或无关类 |(不同包下)子类 |(不同包下)无关类 8 * public(公有) | √ | √ | √ | √ 9 * protected(受保护的) | √ | √ | √ | × 10 * default(默认) | √ | √ | × | × 11 * private(私有) | √ | × | × | × 12 */ 13 14 Sample11 sample11 = new Sample11(); 15 sample11.method1(); 16 sample11.method2(); 17 sample11.method3(); 18 sample11.method4(); 19 } 20 21 public void method1() { 22 System.out.println("public修饰的方法"); 23 } 24 25 protected void method2() { 26 System.out.println("protected修饰的方法"); 27 } 28 29 void method3() { 30 System.out.println("默认修饰的方法"); 31 } 32 33 private void method4() { 34 System.out.println("private修饰的方法"); 35 } 36 }
1 package cn.temptation; 2 3 public class Sample12 extends Sample11 { 4 public static void main(String[] args) { 5 Sample11 sample11 = new Sample11(); 6 sample11.method1(); 7 sample11.method2(); 8 sample11.method3(); 9 // 父类的私有成员方法不能访问 10 // 语法错误:The method method4() from the type Sample11 is not visible 11 // sample11.method4(); 12 13 Sample12 sample12 = new Sample12(); 14 sample12.method1(); 15 sample12.method2(); 16 sample12.method3(); 17 // 父类的私有成员方法不能访问 18 // 语法错误:The method method4() from the type Sample11 is not visible 19 // sample12.method4(); 20 21 } 22 }
1 package cn.temptation; 2 3 public class Sample13 { 4 public static void main(String[] args) { 5 Sample11 sample11 = new Sample11(); 6 sample11.method1(); 7 sample11.method2(); 8 sample11.method3(); 9 // Sample11类的私有成员方法不能访问 10 // 语法错误:The method method4() from the type Sample11 is not visible 11 // sample11.method4(); 12 } 13 }
1 package jp.temptation; 2 3 import cn.temptation.Sample11; // 导入不同的包 4 5 public class Sample14 extends Sample11 { 6 public static void main(String[] args) { 7 Sample11 sample11 = new Sample11(); 8 sample11.method1(); 9 // 语法错误:The method method2() from the type Sample11 is not visible 10 // sample11.method2(); 11 // 语法错误:The method method3() from the type Sample11 is not visible 12 // sample11.method3(); 13 // 语法错误:The method method4() from the type Sample11 is not visible 14 // sample11.method4(); 15 16 // 注意: 17 // 不同包下的子类可以调用自己本类继承而来的protected成员方法 18 // 不同包下的子类中创建的父类对象不能调用自己的protected成员方法 19 Sample14 sample14 = new Sample14(); 20 sample14.method1(); 21 sample14.method2(); 22 // 语法错误:The method method3() from the type Sample11 is not visible 23 // sample14.method3(); 24 // 语法错误:The method method4() from the type Sample11 is not visible 25 // sample14.method4(); 26 } 27 }
1 package jp.temptation; 2 3 import cn.temptation.Sample11; 4 5 public class Sample15 { 6 public static void main(String[] args) { 7 Sample11 sample11 = new Sample11(); 8 sample11.method1(); 9 // 语法错误:The method method2() from the type Sample11 is not visible 10 // sample11.method2(); 11 // 语法错误:The method method3() from the type Sample11 is not visible 12 // sample11.method3(); 13 // 语法错误:The method method4() from the type Sample11 is not visible 14 // sample11.method4(); 15 } 16 }
1 package cn.temptation; 2 3 // 语法错误:Illegal modifier for the class Sample16; only public, abstract & final are permitted 4 //protected class Sample16 { 5 public class Sample16 { 6 // 成员变量 7 public int i = 2; 8 protected int j = 3; 9 int k = 4; 10 private int x = 5; 11 12 public static int y = 6; 13 public final int z = 7; 14 15 // 语法错误:Illegal modifier for the field m; only public, protected, private, static, final, transient & volatile are permitted 16 // public abstract int m = 8; 17 18 // 构造函数 19 // public Sample16() {} 20 // protected Sample16() {} 21 // Sample16() {} 22 // private Sample16() {} 23 24 // 语法错误:Illegal modifier for the constructor in type Sample16; only public, protected & private are permitted 25 // public static Sample16() {} 26 // 语法错误:Illegal modifier for the constructor in type Sample16; only public, protected & private are permitted 27 // public final Sample16() {} 28 29 // 语法错误:Illegal modifier for the constructor in type Sample16; only public, protected & private are permitted 30 // public abstract Sample16() {} 31 32 public static void main(String[] args) { 33 /* 34 * 修饰符的总结 35 * 36 * 权限修饰符 37 * 1)public 38 * 2)protected 39 * 3)default(默认) 40 * 4)private 41 * 42 * 状态修饰符 43 * 1)static 44 * 2)final 45 * 46 * 抽象修饰符 47 * 1)abstract 48 * 49 * --------------------------------------------------- 50 * 51 * 类: 52 * 权限修饰符:public、默认 53 * 状态修饰符:final 54 * 抽象修饰符:abstract 55 * 56 * 成员变量: 57 * 权限修饰符:public、protected、默认、private 58 * 状态修饰符:均可 59 * 抽象修饰符:不可 60 * 61 * 构造函数: 62 * 权限修饰符:public、protected、默认、private 63 * 状态修饰符:不可 64 * 抽象修饰符:不可 65 * 66 * 成员方法: 67 * 权限修饰符:public、protected、默认、private 68 * 状态修饰符:均可 69 * 抽象修饰符:一旦使用了抽象修饰符则成员方法所在的类也必须是抽象的 70 * 71 */ 72 } 73 }