前言
主要对封装、继承、多态这三大特性进行分析以及总结,再举一些实际的案例,便于理解。
一、封装
关于类和对象的知识可以看上一篇文章。
封装:将类的细节进行隐藏,隐藏对象的属性和实现细节,仅对外公开接口与对象进行交互。
例如:一个手机它内部的组成部分是用手机壳盖起来看不见的,它仅提供USB接口、耳机插孔一些接口。
封装增加了安全性。
代码实例(示例):
public class Dog {
//成员变量
private String name;
private String color;
private int age;
//无参构造方法
public Dog() {
}
//有参构造方法
public Dog(String name, String color, int age) {
this.name = name;
this.color = color;
this.age = age;
}
//成员方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
二、继承
1.概念:抽取代码中的共性,提高代码的复用性。
关键字:extends
2.super:子类从父类继承过来的内存
3.super的三个用法:
(1)super.属性:调用父类属性
(2)super.方法名:调用父类方法
(3)super():调用父类构造方法
注意:子类再构造时需要先使用super将父类构造完整。
4.super和this的区别:
1.引入案例1
无参构造方法
代码如下(示例):
/**
* 父类(基类)
*/
class Base {
String name;
int age;
//默认
/*Base() {
}*/
@Override
public String toString() {
return "Base{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
/**
* 子类(派生类)
*/
class Derived extends Base{
double weight;
//默认
Derived() {
super();
}
@Override
public String toString() {
return "Derived{" +
"name='" + name + '\'' +
", age=" + age +
", weight=" + weight +
'}';
}
}
public class TestDemo1 {
public static void main(String[] args) {
Base base = new Base();
base.name = "父类";
base.age = 20;
System.out.println(base);
Derived derived = new Derived();
derived.weight = 1.0;
derived.name = "子类";
derived.age = 10;
System.out.println(derived);
}
}
2.引入案例2
有参构造方法
代码如下(示例):
/**
* 父类:动物
*/
class Animal {
String name;
int age;
//有参构造方法
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
}
class Dog extends Animal{
private String run;
//子类有参构造方法
public Dog(String name, int age, String run) {
super(name, age);//super调用父类构造方法
this.run = run;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
", run='" + run + '\'' +
'}';
}
}
class Cat extends Animal {
private double weight;
public Cat(String name, int age, double weight) {
super(name, age);
this.weight = weight;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
", weight=" + weight +
'}';
}
}
public class TestDemo2 {
public static void main(String[] args) {
Dog dog = new Dog("小狗",10,"正在跑");
System.out.println(dog);
Cat cat = new Cat("小猫",5,4.9);
System.out.println(cat);
}
}
3.再谈初始化
执行顺序:
1.父类和子类的静态代码块
2.父类的实例和构造
3.子类的实例和构造
代码如下(示例):
class Base2 {
static {
System.out.println("父类:静态代码块");
}
{
System.out.println("父类:实例代码块");
}
public Base2() {
System.out.println("父类构造方法");
}
}
class Derived2 extends Base2{
static {
System.out.println("子类:静态代码块");
}
{
System.out.println("子类:实例代码块");
}
public Derived2() {
super();
System.out.println("子类构造方法");
}
}
public class TestDemo3 {
public static void main(String[] args) {
Derived2 derived2 = new Derived2();
}
}
输出结果:
三、多态
实现条件
1、必须在继承的体系下(完成向上转型);
向上转型的三种情况:
(1)直接赋值
class animal {
String name;
public void eat() {
System.out.println("Animal:eat");
}
}
class cat extends animal{
@Override
public void eat() {
System.out.println("cat:eat");
}
}
public class TestDemo4 {
public static void main(String[] args) {
animal animal1 = new cat();//直接赋值
}
}
(2)方法传参
class animal {
String name;
public void eat() {
System.out.println("Animal:eat");
}
}
class cat extends animal{
@Override
public void eat() {
System.out.println("cat:eat");
}
}
public class TestDemo4 {
//方法传参
public static void transform(animal animal) {
System.out.println("trans");
}
public static void main(String[] args) {
cat cat1 = new cat();
transform(cat1);
}
}
(3)返回值
class animal {
String name;
public void eat() {
System.out.println("Animal:eat");
}
}
class cat extends animal{
@Override
public void eat() {
System.out.println("cat:eat");
}
}
public class TestDemo4 {
public static animal trans() {
return new cat();
}
public static void main(String[] args) {
animal animal3 = trans();
}
}
2、子类必须对父类中的方法重写;
3、通过父类的引用调用重写的方法(发生了动态绑定)。
代码如下(示例):
class Animals {
String name;
int age;
public Animals(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("姓名:"+name+" 年龄:"+age+"正在吃~");
}
}
class Dogs extends Animals{
public Dogs(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("姓名:"+name+" 年龄:"+age+"正在吃垃圾");
}
}
class Cats extends Animals{
public Cats(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("姓名:"+name+" 年龄:"+age+"正在吃小鱼");
}
}
public class TestDemo5 {
public static void function(Animals animals) {
animals.eat();
}
public static void main(String[] args) {
//实现多态
function(new Dogs("小白狗",1));
function(new Cats("小花猫",2));
//向下转型
System.out.println("============向下转型=============");
Animals animals = new Dogs("小黑狗",2);
if(animals instanceof Cats) {
Cats cats = (Cats) animals;
cats.eat();
}
if(animals instanceof Dogs) {
Dogs dogs = (Dogs) animals;
dogs.eat();
}
}
}
重写和重载
重写不能改变参数列表、返回类型并且子类的访问限定权限要大于父类的访问限定权限。(加上final的方法不能被重写)
重载必须改变参数列表(参数的个数、类型、顺序)和返回类型并且访问限定符也可以修改。
总结
过了这么久终于把面向对象的三大特征总结了一下,主要是为了加深印象。。。