一、封装
- 概念:尽可能的隐藏对象内部的事先细节,控制对象的修改及访问权限,使得程序不能被外部随意访问,提高了安全性。
- 封装使用访问修饰符private(可将属性修饰为私有,仅在本类中可访问)
- 封装以后提供get、set方法让外界调用,我们也可以在get和set方法中指定相应规则来规范程序
//////////////////////////////未封装的代码//////////////////////////////////////////////// public class Demo01 { public static void main(String[] args) { Stu stu01 = new Stu(); stu01.name = "张三"; stu01.age = 23; stu01.show(); Stu stu02 = new Stu(); stu02.name = "李思思"; // 年龄的范围符合语法,但是不符合生产需求 stu02.age = 2444; stu02.show(); } } class Stu{ // 属性 String name; int age; String gender; String addr; // 方法 public void show() { System.out.println("我的名字是" + name + ",我今年" + age); } } //////////////////////////////封装后的代码//////////////////////////////////////////////// public class Demo02 { public static void main(String[] args) { Student s01 = new Student(); s01.name = "王五"; s01.setAge(25); s01.show(); } } class Student{ // 属性 String name; // 私有化属性age private int age; public void setAge(int age) { this.age = age; } public int getAge() { return this.age; } // 方法 public void show() { System.out.println("我的名字叫" + name + ",我今年" + age); } }
-
-
1 class Students{ 2 // 属性 3 String name; 4 private int age; 5 6 // 构造方法 7 public Students() { 8 super(); 9 } 10 11 public Students(String name, int age) { 12 super(); 13 // 构造方法可以逃过set和get方法直接给属性赋值 14 this.name = name; 15 // 如果想要set中的规则继续生效就在构造方法中调用set和get方法 16 this.setAge(age); 17 }
二、继承
- 概念:子类从父类中获取的属性和方法;子类通过关键字extends和这个类产生继承关系;类和父类需要满足一个条件【子类 is a 父类】
- 语法格式: 子类的代码 }
-
继承的特点:
- Java是单继承【一个类只能有一个直接的父类,但父类中可以在有父类】
- Java可以多级继承,子类可以获取到父类属性和方法,也可以获取到父类的父类的属性和方法
- 优点:提高了代码的复用性,又提高代码的可扩展性
-
不可继承:
- 父类的构造方法不可继承【由于类的构造方法只负责本类对象,所以不可继承】
- private修饰的属性和方法不可继承【private修饰的属性和方法作用范围只限于本类,因此不可继承】
- 父子类不在同一个package中时,default修饰的属性和方法:【default修饰的属性和方法作用范围仅在同包下】
- 图解【访问修饰符】
本类 | 同包 | 非同包子类 | 其他 | |
private | true | false | false | false |
default | true | true | false | false |
protected | true | true | true | false |
public | true | true | true | true |
三、方法重写\覆盖【Override】==》有继承关系
- 概念:子类继承父类的属性和方法时,父类的方法无法满足子类的需求,可在子类中定义和父类相同的方法进行重写【Override】 重写的原则【可使用@Override注解来验证是否重写】
- 方法名称、参数列表、返回值类型必须和父类相同
- 访问修饰符可与父类相同或比父类更广
- 方法重写执行:
- 子类重写父类方法后,调用时优先执行子类重写后的方法
- 案例:
1 public class Demo01 { 2 public static void main(String[] args) { 3 // 方法重写案例 4 WeChatV1 w01 = new WeChatV1(); 5 w01.chat(); 6 7 WeChatV2 w02 = new WeChatV2(); 8 w02.chat(); 9 10 } 11 } 12 13 class WeChatV1{ 14 public void chat() { 15 System.out.println("微信第一版跨时代产品上市,能通过网络发消息,发消息免费."); 16 } 17 } 18 19 classs WeChatV2 extends WeChatV1{ 20 @Override 21 public void chat() { 22 System.out.println("微信第二版隆重上市,可以通过网络发送语音消息,每人每天可免费发出200条"); 23 } 24 }
四、关键字super
- 定义:子类继承父类后,获取到父类的属性和方法有可能与子类的属性和方法重名。使用super可区分子类与父类的属性和方法
- super调用属性和方法
- super.方法名(参数列表)==》调用父类的方法
- super.属性名==》调用父类的属性
- super调用父类的构造方法
- super(参数列表)==》调用父类构造方法
- 案例:
1 class Dog extends Animal{ 2 public Dog() { 3 //调用无参构造 4 super(); 5 } 6 7 public Dog(String type, String name, int age, String gender) { 8 // 调用父类有参数的构造方法 9 super(type, name, age, gender); 10 } 11 }
- this和super
- 调用属性
- this.属性 == 》调用子类自己的属性
- super.属性 ==》调用父类的属性
- 调用方法
- this.方法名(参数列表)==》调用子类自己的方法
- super.方法名(参数列表)==》调用父类的方法
- 调用构造方法
- this(参数列表)==》 调用子类自己的构造方法
- super(参数列表)==》调用父类的构造方法
- 注意:
- 在调用构造方法的时候,this和super不能同时存在
- 子类的构造方法会默认调用父类的空参构造方法
- this和super必须放在首行
- 调用属性
五、多态
- 概念:父类引用指向子类对象,从而产生多态
- 语法格式:Animal a = new Dog(); ==》Animal:父类类型(引用);Dog():子类对象(对象类型)
- 二者具有直接或间接的继承关系时,父类引用可指向子类对象,即形成多态。
- 父类引用仅可调用父类所声明的属性和方法,不可调用子类的独有属性和方法
- 多态使用方法和属性调用情况:
- 调用方法:
- 编译时候看父类中是否有这个方法,运行时看子类是否重写过该方法。【编译看左边,运行看右边】
- 调用属性:
- 编译时候看父类是都存在该属性,运行时候也是看父类是否存在该方法。【编译看左边,运行看左边】
- 调用方法:
- 定义:判断一个对象是否是指定类型的实例
- 案例
1 import java.util.Scanner; 2 3 public class Demo06 { 4 public static void main(String[] args) { 5 /** 6 * 传入一个对象,调用这个对象所有的方法 7 */ 8 System.out.println("" instanceof String); 9 10 /** 11 * 提示用书输入一个数字,调用getPerson方法,获取这个数字对应的对象 12 * 调用show方法,传入这个对象,展示这个对象的方法 13 */ 14 15 Scanner in = new Scanner(System.in); 16 System.out.println("请输入你希望看到的职业(1==SoftwareEngineer,,,2==DBA,,,3==ImplementationEngineer,,,其他数字==Person):"); 17 int num = in.nextInt(); 18 // 调用getPerson方法获取对象 19 Person person = getPerson(num); 20 21 // 调用show方法传入Person。展示这个职业的方法 22 show(person); 23 24 } 25 26 /** 27 * 传入数字,获取对应的Person或者其子类的对象 28 * @param num- 29 * @return 30 */ 31 public static Person getPerson(int num) { 32 Person person; 33 switch (num) { 34 case 1: 35 person = new SoftwareEngineer(); 36 break; 37 38 case 2: 39 person = new DBA(); 40 break; 41 42 case 3: 43 person = new ImplementationEngineer(); 44 break; 45 46 default: 47 person = new Person(); 48 break; 49 } 50 51 return person; 52 } 53 54 55 /** 56 * 展示Person或者其子类的所有方法 57 * @param person 58 */ 59 public static void show(Person person) { 60 if (person == null) { 61 System.out.println("Person为null,请重新执行代码传入正确的参数..."); 62 return; 63 } 64 65 // person非null 66 if (person instanceof SoftwareEngineer) { 67 SoftwareEngineer engineer = (SoftwareEngineer) person; 68 engineer.eat(); 69 engineer.sleep(); 70 engineer.work(); 71 } else if (person instanceof DBA) { 72 DBA dba = (DBA) person; 73 dba.eat(); 74 dba.sleep(); 75 dba.eatBraisedChicken(); 76 } else if (person instanceof ImplementationEngineer) { 77 ImplementationEngineer engineer = (ImplementationEngineer) person; 78 engineer.eat(); 79 engineer.sleep(); 80 engineer.work(); 81 } else if (person instanceof Person) { 82 person.eat(); 83 person.sleep(); 84 } else { 85 System.out.println("您选择的职业暂无相关信息..."); 86 } 87 } 88 } 89 90 /** 父类 91 * 会有一些子类,子类是具体职业的人 92 * 93 */ 94 class Person{ 95 public void eat() { 96 System.out.println("人类需要吃饭..."); 97 } 98 99 public void sleep() { 100 System.out.println("人需要睡眠保持精力..."); 101 } 102 } 103 104 /** 105 * 技术总监/经理 106 * 技术支持/维护 技术专员 107 * 助理 软件工程师 108 * 程序员 109 * 硬件工程师 110 * 质量工程师 111 * 测试工程师 112 * 系统架构师 113 * 数据库管理/DBA 114 * 游戏设计 115 * 开发 116 * 网页设计/制作 117 * 语音/视频/图形 118 * 项目经理/主管 119 * 产品经理/专员 120 * 网站运营 121 * 网站编辑 122 * 网站策划 123 * 网络管理员 网络与信息安全工程师 实施工程师 通信技术工程师 124 * */ 125 126 /** 127 * 软件工程师类 128 * 继承Person 129 * 重写eat和sleep方法 130 * 自定义work方法 131 * @author Dushine2008 132 * 133 */ 134 class SoftwareEngineer extends Person{ 135 136 @Override 137 public void eat() { 138 System.out.println("我们工作很忙,外卖解决吃饭的问题..."); 139 } 140 141 public void sleep() { 142 System.out.println("我们每天坚持午睡,下午精力充沛..."); 143 } 144 145 public void work() { 146 System.out.println("我们的工作白天不怎么忙,晚上经常加班..."); 147 } 148 } 149 150 /** 151 * DBA类 152 * 继承Person 153 * 重写eat和work 154 * 自定义eatBraisedChicken方法 155 * @author Dushine2008 156 * 157 */ 158 class DBA extends Person { 159 160 @Override 161 public void eat() { 162 System.out.println("DBA数据库方面的造诣比较深厚,他们吃饭也是点外卖,靠入侵外卖平台的数据库,篡改订单信息吃饭."); 163 } 164 165 public void sleep() { 166 System.out.println("中午不睡下午崩溃,坚持在你午睡攻陷你家的数据库."); 167 } 168 169 public void eatBraisedChicken() { 170 System.out.println("靠技术吃黄焖鸡,吃了整整一年..."); 171 } 172 173 } 174 175 /** 176 * 实施工程师 177 * 继承Person 178 * 重写eat和sleep方法 179 * 自定义work方法 180 * @author Dushine2008 181 * 182 */ 183 class ImplementationEngineer extends Person{ 184 @Override 185 public void eat() { 186 System.out.println("经常出差,可以领略各地的美食..."); 187 } 188 189 @Override 190 public void sleep() { 191 System.out.println("一年到头就处于开房和退房的路上..."); 192 } 193 194 public void work() { 195 System.out.println("这是个根客户打交道比较多的工作..."); 196 } 197 }