一、封装:
封装的概念:
- 合理的隐藏:隐藏不想被外界操作的Field、方法、构造器
- 合理的暴露:一般就是希望给别人调用的方法
e.g:显示器(按键暴露出来操作,但实际的东西/细节方法被隐藏起来)
封装的目的:
- 简化编程(不去去找显示器的内部调,直接按键调整即可)
- 更好的保证对象的完整性
为了实现隐藏,我们有4个修饰符:
private - 仅限当前类访问权限
无修饰符/默认 - 包访问权限(同一个包内)
protected - 子类访问权限(本类能访问、同一个包也能访问)
public - 公共的访问权限
权限级别:private → 默认访问权限 → protected → public (只有成员变量才需用访问权限修饰符)
private - 用于隐藏Field
public - 专门用于暴露方法
protected - 希望被它的子类访问的方法
默认 - 希望在同一个包中被访问
局部变量方法一执行完就销毁了,所以没必要限制,限制了也没意义,它尽在方法内或代码块中有效,作用域本来就小-连方法都出不了,所以它用访问权限修饰符都是多余(默认都多余)
1 class Fruit { 2 private double weight; 3 private String name; 4 5 public void grow(double grow){ 6 if(this.weight + grow >= 100){ 7 System.out.println("水果超出重量,逆天了!"); 8 }else{ 9 weight = weight + grow; 10 } 11 } 12 13 public void setName(String name){ 14 if(name.length() > 6 || name.length() < 2){ 15 System.out.println("水果名字不符合规则"); 16 }else{ 17 this.name = name; 18 } 19 } 20 21 public void info(){ 22 System.out.println("这个是:" + name + ",重量为:" + weight); 23 } 24 }
1 class TestFruit{ 2 public static void main(String[] args){ 3 Fruit t = new Fruit(); 4 //t.weight = 200; 定义为private后不能直接赋值 5 //t.name = "Apple"; 如果直接赋值将破坏Fruit对象的数据完整性 6 t.grow(10); 7 //t.grow(101); //不符合定义规则打印对应语句 8 //t.setName("A"); 9 t.setName("Apple"); 10 t.info(); 11 } 12 }
二、继承:(extends)
Java的继承 - 两个类之间的关系(A extends B),Java中的继承从"一般到特殊"的关系,如:
人 → 老师 → IT老师 → 教Java的老师
Java通过关键字extends来实现,实现继承的类称为子类,被继承的类称为基类/超类/父类,父类是大类(范围大),子类是小类
Java的继承是单继承,每个继承类(extends后面)只能有一个直接父类但可以有N个间接父类,子类继承了父类 仅【能】获得父类的全部属性和方法但【不能】获得父类的构造器、初始化块、内部类
如果定义的Java类没有显示的指定父类,系统默认会让它继承Object类--一切的类都是Object类的子类
1 public class Person { 2 private String name; 3 private int age; 4 5 public Person(){} //父类空构造器,子类初始化是会报错 6 7 public Person(String name , int age){ 8 this.name = name; 9 this.age = age; 10 } 11 12 public void info(){ 13 System.out.println("这人叫:" + name + ",年龄是:" + age); 14 } 15 16 public static void main(String[] args) { 17 Person p = new Person("小二",20); 18 p.info(); 19 } 20 }
1 public class Teacher extends Person{ 2 public static void main(String[] args){ 3 //子类将会从父类那里获取到所有方法 4 Teacher t = new Teacher(); 5 //调用从父类那里继承到的方法 6 t.info(); 7 } 8 }
继承中父类与子类的关系是"一般到特殊的关系",所以子类的实例完全可以当作父类的对象来使用,父类的引用变量完全可以指向子类的实例。
1 class Animal{ 2 private String name; 3 private String sex; 4 5 public Animal(String name , String sex){ 6 this.name = name; 7 this.sex = sex; 8 } 9 10 public void info(){ 11 System.out.println("动物的名字叫:" + name + ",性别为:" + sex); 12 } 13 } 14 15 public class TestAnimal extends Animal{ 16 private String color; 17 18 public TestAnimal(String name , String sex , String color){ 19 super(name,sex); 20 this.color = color; 21 } 22 23 public static void test(Animal A){ 24 System.out.println("~这是个测试方法~"); 25 A.info(); 26 } 27 28 public static void main(String[] args){ 29 Animal ta = new TestAnimal("灰太狼","male","灰色"); 30 TestAnimal.test(ta); 31 } 32 }
三、多态:
同一类型的变量,在访问同一方法时, 呈现出多种行为特征 -- 这就是多态。
多态增加了Java语言的灵活性,它是和设计模式紧密相连的。
1 class Person{ 2 public void work(){ 3 System.out.println("努力工作!"); 4 } 5 } 6 7 class Teacher extends Person{ 8 @Override 9 public void work(){ 10 System.out.println("辛勤的教书!"); 11 } 12 } 13 14 class Student extends Person{ 15 @Override 16 public void work(){ 17 System.out.println("努力的读书!"); 18 } 19 20 public void play(){ 21 System.out.println("读书真累啊!"); 22 System.out.println("累的时候也要适当的玩耍啊!"); 23 } 24 } 25 26 public class Duotai{ 27 public static void main(String[] args) { 28 //多态:同一个类型的变量在访问同一个方法时,表现出多种行为特征 29 //p、p1、p2均为person类型变量,但在访问work方法时返回的结果都不一样则为多态 30 Person p = new Person(); 31 p.work(); 32 //子类的实例/对象完全可以当成父类的对象来使用 33 //p1引用变量指向Teacher实例 34 Person p1 = new Teacher(); 35 p1.work(); 36 Person p2 = new Student(); 37 p2.work(); 38 //编译阶段不管运行时类型的,编译器并不知道引用变量实际引用的对象时Student,编译器只知道它的编译时类型为Person,而Person又没有play()方法,所以编译报错 39 //p2.play(); 40 //若要调用play()方法,则可以使用Student来定义变量,或者使用强制转换将p2转换成student对象 41 Student st = (Student)p2; 42 st.play(); 43 44 Student p3 = new Student(); 45 p3.play(); 46 } 47 }
Java的引用变量有两个类型:
1、编译时类型:由声明它的类型来决定所以p、p1、p2的编译类型均为Person,p3的编译类型为Student;
2、运行时类型:由该引用变量实际所指向的对象决定p的为Person,p1 为Teacher, p2为Student,p3为Student,当我们调用引用变量时,它总是呈现它的运行时的特征.