1.封装
封装:就是隐藏对象的属性和实现细节,仅对外提供公共访问方式。
封装的好处:隐藏类的实现细节;让使用者只能通过程序员规定的方法来访问数据;可以方便的加入存取控制语句,限制不合理操作.
封装时的权限控制符区别如下:
代码实现如下:
private关键字:
/**
* 描述人。Person
* 属性:年龄。
* 行为:说话:说出自己的年龄
*/
public class Person
{
int age ;// 年龄
String name;// 姓名
public void show()// 展示
{
System.out.println("age="+age+",name"+name);
}
}
class PersonDemo
{
public static void main(String[] args)
{
//创建Person对象
Person p = new Person();
p.age = -20; // 给Person对象赋值
p.name = "人妖";
p.show(); //调用Person的show方法
}
}
注意:私有仅仅是封装的体现形式而已。
2.继承
语法:
关键词:extends
在java中,继承通过extends关键字来实现,其中SubClass称为子类,SuperClass称为父类。修饰符如果是public,该类在整个项目中可见;不写public修饰符则该类只在当前包可用;不可以使用private和protected修饰符.
//将学生和工人的共性抽取到Person这个类中
class Person {
String name;
int age;
}
//学生通过extends继承Person,即Person为Student的父类
class Student extends Person{
//学生类中的自己特有方法
public void study(){
System.out.println(name+"同学正在学习。。。。");
}
}
//工人通过extends继承Person,即Person为工人的父类
class Worker extends Person{
//工人类中的自己特有方法
public void work(){
System.out.println(name+"工人正在工作。。。。");
}
}
//测试类
public class Test{
public static void main(String[] args) {
Student s = new Student();
s.name = "小明";
s.study();
Worker w = new Worker();
w.name = "张三";
w.work();
}
}
继承:是 java 中实现代码重用的重要手段之一.java中只支持单继承,即每个类只能有一个父类.继承表达的是 is a 的关系,或者说是一种特殊和一般的关系.
在java中,所有的java类都直接或间的接的继承了java.lang.long.Object类.Object类是所有java类的祖先.在定义一个类时,没有使用 extends 关键字,那么这个类直接继承Object类.
在java中,子类可以从父类中继承的有:
继承 public 和 protected 修饰的属性和方法,不管子类和父类是否在同一个包里。
继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里。
子类无法继承父类的有:
无法继承 private 修饰的属性和方法
无法继承父类的构造方法
如果从父类继承的方法不能满足子类的需求,在子类中可以对父类的同名方法进行重写 ,以符合要求.
抽象出Dog类和Penguin类和父类Pet类(Pet类为抽象类,不能被实例化)
Java继承:
1、Java只支持单继承,也就是只能继承一个类
2、如果一个类没有声明继承关系,默认继承Object类
3、子类继承父类全部的操作(除了构造方法),如果父类中的属性是private的,属于隐
式继承,不能直接 操作,可以通过set、get方法进行操作
在子类中,可以根据需要对从基类中继承来的方法进行重写
重写方法必须和被重写方法具有相同的方法名称、参数列表、和返回类型
重写方法不能使用比被重写方法更更严格的访问权限
3.多态
多态的三个条件:
1. 继承的存在(继承是多态的基础,没有继承就没有多态).
2. 子类重写父类的方法(多态下调用子类重写的方法).
3. 父类引用变量指向子类对象(子类到父类的类型转换).
子类转换成父类时的规则:
将一个父类的引用指向一个子类的对象,称为向上转型(upcastiog),自动进行类型转换.
此时通过父类引用调用的方法是子类覆盖或继承父类的方法,不是父类的方法.
此时通过父类引用变量无法调用子类特有的方法.
如果父类要调用子类的特有方法就得将一个指向子类对象的父类引用赋给一个子类的引用,称为向下转型,此时必须进行强制类型转换.
//描述狗,狗有吃饭,看家的行为
class Dog
{
public void eat()
{
System.out.println("啃骨头");
}
public void lookHome()
{
System.out.println("看家");
}
}
//描述猫,猫有吃饭,抓老鼠行为
class Cat
{
public void eat()
{
System.out.println("吃鱼");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
/*有多个狗和猫对象都要调用吃饭这个行为
这样会导致d.eat();代码重复性非常严重
Dog d = new Dog();
d.eat();
为了提高代码的复用性,可以将d.eat();代码进行封装
public static void method(Dog d)
{
d.eat();
}
然后创建对象,直接调用method方法即可
method(new Dog());
method(new Dog());
但当创建Cat对象时,同样需要调用eat方法,同样可以将eat方法进行封装
public static void method(Cat c)
{
c.eat();
}
*/
}
}
后期当有了猪对象时,那么同样要封装eat方法,当每多一个动物,都要单独定义功能,封装方法让动物的对象去做事,会发现代码的扩展性很差。如何提高代码的扩展性呢?发现既然是让动物去eat,无论是dog,还是cat,eat是他们的共性,那么将eat进行抽取,抽取到父类中。
abstract class Animal { //由于每一个小动物的eat方式都不一样,因此在父类中无法准确描述eat的具体行为 //因此只能使用抽象方法描述,从而导致这个类也为抽象类 abstract public void eat(); }
当有了Animal抽象类之后,狗和猫只要继承这个类,实现他们特有的eat方法即可
//描述狗,狗有吃饭,看家的行为 class Dog extends Animal { public void eat() { System.out.println("啃骨头"); } public void lookHome() { System.out.println("看家"); } } //描述猫,猫有吃饭,抓老鼠行为 class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void catchMouse() { System.out.println("抓老鼠"); } }
既然Dog
属于Animal中一种,Cat
也属于Animal中一种,那么不用具体面对具体的动物,而只要面对Animal即可。
Dog d = new Dog(); Animal a = new Dog(); Cat c = new Cat(); Animal aa = new Cat();
通过上述代码发现,Animal类型既可以接受Dog
类型,也可以接受Cat
类型,当再让动物去做事时,不用面对具体的动物,而只要面对Animal即可。因此上述method方法可以修改为:
// 多态 public static void method(Animal a) { a.eat(); }
method(Animal a)
可以接受Animal的子类型的所有小动物,而method方法不用在关心是具体的哪一个类型。即就是只建立Animal的引用就可以接收所有的Dog和Cat对象进来,让它们去eat。从而提高了程序的扩展性。
多态的好处:
提高了程序的扩展性和复用性。
多态的弊端:
通过父类引用操作子类对象时,只能使用父类中已有的方法,不能操作子类特有的方法。
多态的前提:
-
必须有关系:
继承,实现
。 -
通常都有
重写
操作。