面向对象的三大特征:封装 继承 多态.
一.简述面象对象
面向对象就是采用”现实模拟”的方法设计和开发程序.
面向对象技术利用”面向对象的思想”去描述面象对象的世界,实现了虚拟世界和现实世界的一致性,符合人们的生活习惯,使得客户和软件开发人员之间,软件设计人员内部交流更加顺畅,同时还带来了代码重用性高,可靠性高等优点,大大提高了软件尤其是大型软件的设计和开发效率.
面向对象和面向对象的区别(简述)
面向过程的核心概念是函数,以功能为中心,实现了函数级别的代码重用.面向对象的核心概念是封装了属性和方法(行为的类),以数据为中心,实现了类级别的代码重用.面向对象因为采用了类,具有继承和多态特性,可以进一步重用代码和间简化编程,而面向过程中没有继承和多态特性.
面向对象的设计过程就是抽象的过程(发现类,发现类的属性,发现类的方法).
类和对象是面向对象中的两个核心概念
类:是对某一类事物的描述,是抽象的,概念上的定义.
对象:是实际存在的该事物的个体,是具体的,现实的.类和对象就好比模具和铸件的关系,建筑物图纸和建筑物实物的关系.一个类可以创建多个对象.
二.面向对象的三大持征(封装,继承,多态)
1.封装
封装(Encapsulation):是类的三大特征之一,就是将类的状态信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问.简而言之就是隐藏对象的属性和实现细节,仅对外提供公共访问方式.
封装的具体步骤:修改属性的可见性来限制对属性的访问;为每个属性创建一对赋值(setter)方法和取值(getter)方法,用于对这些属性的存取;在赋值方法中,加入对属性的存取控制语句.
封装的好处主要有:隐藏类的实现细节;让使用者只能通过程序员规定的方法来访问数据;可以方便的加入存取控制语句,限制不合理操作.
封装时的权限控制符区别如下:
Ø private:成员变量和方法只能在类内被访问,具有类可见性.
Ø 默认:成员变量和方法只能被同一个包里的类访问,具有包可见性.
Ø protected:可以被同一个包中的类访问,被同一个项目中不同包中的子类访问.
Ø public:可以被同一个项目中所有类访问,具有项目可见性,这是最大的访问权限.
举例:
Penguin类和Dog类图
封装代码:
public class Dog
{
/*
* 封装演示
* */
//私有化属性
private Stringname;
private Stringsex;
private Stringcolor;
//封装字段
public StringgetName()
{
returnname;
}
public voidsetName(String name)
{
this.name = name;
}
public StringgetSex()
{
returnsex;
}
public voidsetSex(String sex)
{
this.sex = sex;
}
public StringgetColor()
{
returncolor;
}
public voidsetColor(String color)
{
this.color = color;
}
}
Penguin类同理
2.继承
语法:
修饰符SubClass extends SuperClass{
//类定义部分
}
在java中,继承通过extends关键字来实现,其中SubClass称为子类,SuperClass称为父类,基类,或超类.修饰符如果是public,该类在整个项目中可见;不写public修饰符则该类只在当前包可前;不可以使用private和protected修饰符.
继承(Inheritance):是java中实现代码重用的重要手段之一.java中只支持单继承,即每个类只能有一个父类.继承表达的是isa的关系,或者说是一种特殊和一般的关系.
在java中,所有的java类都直接或间的接的继承了java.lang.long.Object类.Object类是所有java类的祖先.在定义一个类时,没有使用extends关键字,那么这个类直接继承Object类.
在java中,子类可以从父类中继承的有:
Ø 继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包里.
Ø 继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里.
子类无法继承父类的有:
Ø 无法继承private修饰的属性和方法
Ø 无法继承父类的构造方法
如果从父类继承的方法不能满足子类的需求,在子类中可以对父类的同名方法进行重写(覆盖),以符合要求.
抽象出Dog类和Penguin类和父类Pet类(Pet类为抽象类,不能被实例化)
/*
* Dog和Penguin的父类Pet,而Pet对象是没有意义的,只是抽象出来的一个概念,国此给Pet类添* 加abstract修饰符,让其成为一个抽象类,抽象不能被实例化.
* */
public abstract class Pet
{
//私有化属性
private Stringname;
private Stringsex;
//封装字段
public StringgetName()
{
returnname;
}
public voidsetName(String name)
{
this.name = name;
}
public StringgetSex()
{
returnsex;
}
public voidsetSex(String sex)
{
this.sex = sex;
}
//无参构造方法
public Pet()
{
}
/*
* 有参构造方法
* @param name 名称
* @param sex 性别
*
* */
publicPet(String name, String sex)
{
this.setName(name);
this.setSex(sex);
}
//Pet类的抽象方法eat(),抽象方法必需被子类重写
publicabstract void eat()
//final修饰的方法不能被子类重写
publicfinalvoid println()
{
//方法体…
}
}
//狗继承动物类
class Dog extends Pet
{
private Stringcolor;
//封装字段
public StringgetColor()
{
returncolor;
}
public voidsetColor(String color)
{
this.color = color;
}
//无参构造方法
public Dog()
{
}
//有参构造方法
publicDog(String name, String sex, String color)
{
//传参到父类的构造方法,此处不能用this.name = name.....
super(name,sex);
//调用setColor()方法给属性color赋值
this.setColor(color);
}
//重写父类eat()方法
public void eat()
{
//方法体....
}
}
//企鹅继承动物类
class Penguinextends Pet
{
private double weight;
public doublegetWeight()
{
returnweight;
}
public voidsetWeight(double weight)
{
this.weight = weight;
}
//重写父类eat()方法
public void eat()
{
//方法体….
}
}
//测试类Test
class Test
{
public static voidmain(String[] args)
{
String name= "dog1";
String sex ="男";
String color= "red";
//实例化对象
Dog dog = new Dog();
dog.setName(name); //通过从父类处继承来的方法设置dog的属性name
dog.setSex(sex);
//通过有参构造函数实例化对象
Dog dog1 = new Dog("dogName","man", "black");
//调用eat()方法,此方法被重写了
dog1.eat();
}
}
继承条件下构造方法调用规则如下
Ø 如果子类的构造方法中没有通过super显示调用父类的有参构造方法,也没有通过this显示调用自身的其他构造方法,则系统会默认先调用父类的无参构造 方法.在这种情况下写不写super()语句效果都是一样.
Ø 如果子类的构造方法中通过super显示调用父类的有参构造方法,那将执行父类相应构造方法,而不执行父类无参构造方法.
Ø 如果子类的构造方法中通过this显示调用自身的其他构造方法,在相应 构造方法中应用以上两条规则.
Ø 特别注意的是,如果存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类应用,一直到执行顶级父类Object类的无参构造方法为止.
abstract和final是功能相反的两个关键字,abstract可以用来修饰类和方法,不能用来修饰属性和构造方法.final可以用来修饰类,方法和属性,不能修饰构造方法.
3.多态
多态(Polymorphism):是指具有表现多种形态的能力特征.更专业的说法是:同一个实现接口,使用不同的实例而执行不同的操作.
多态的三个条件:
1. 继承的存在(继承是多态的基础,没有继承就没有多态).
2. 子类重写父类的方法(多态下调用子类重写的方法).
3. 父类引用变量指向子类对象(子类到父类的类型转换).
子类转换成父类时的规则:
Ø 将一个父类的引用指向一个子类的对象,称为向上转型(upcastiog),自动进行类型转换.
Ø 此时通过父类引用调用的方法是子类覆盖或继承父类的方法,不是父类的方法.
Ø 此时通过父类引用变量无法调用子类特有的方法.
如果父类要调用子类的特有方法就得将一个指向子类对象的父类引用赋给一个子类的引用,称为向下转型,此时必须进行强制类型转换.
练习:
public class Person //人类
{
String name;
int age;
public void eat()
{
System.out.println("人们在吃饭!");
}
}
class Chineseextends Person
{
//重写父类方法
public void eat()
{
System.out.println("中国人在吃饭!");
}
//子类特有方法,当父类引用指向子类对象时无法调用该方法
public voidshadowBoxing()
{
System.out.println("练习太极拳!");
}
}
class Englishextends Person
{
//重写父类方法
public void eat()
{
System.out.println("英国人在吃饭!");
}
}
//测试类
class TestEat
{
public static voidmain(String[] args)
{
TestEat test= newTestEat();
//引用指向中国人,创建中国人类对象
Personperson1 = new Chinese();
//此时调用的是Chinese的eat()方法
test.showEat(person1);
Personperson2 = new English();
//此时调用的是English的eat()方法
test.showEat(person2);
//强制类型转换(向下转型)
Chinesechinese = (Chinese)person1;
//向下转型后,调用子类的特有方法
chinese.shadowBoxing();
}
//使用父类作为方法的形参,实现多态
public voidshowEat(Person person)
{
//传入的是哪具对象就调用哪个对象的eat()方法
person.eat();
}
}