今天要学习的内容有:
- 面向对象特征--封装(补充)
- 面向对象特征--继承
- 抽象类
封装
接着上次封装的知识。
单例模式:需要某个类在整个应用程序中,只能创建一个类。
//懒汉式单例
public class Demo1 {
static Demo1 demo1=null;
private Demo1() {
}
public static Demo1 getDemo1(){
if (demo1==null){
demo1=new Demo1();
}
return demo1;
}
}
//饿汉式单例
public class Demo2 {
static Demo2 demo2=new Demo2();
private Demo2() {
}
public static Demo2 getDemo2(){
return demo2;
}
}
public class TestDemo1 {
public static void main(String[] args) {
Demo1 d1=Demo1.getDemo1();
Demo1 d2=Demo1.getDemo1();
Demo1 d3=Demo1.getDemo1();
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
}
}
运行结果:
可见创建的三个实例都是一个地址,所以其实只创建了一个,只能创建一个实例。
继承
继承的概念:
继承是面对对象的三大特征之一。继承是一个类,从已经有的类继承已有的属性和行为,并扩展新的能力。被继承的叫父类,新的类叫子类。
使用继承时,我们使用extends来表示继承关系,且一个类只能继承一个父类,继承之后子类可以调用父类的所有非私有属性和非私有方法。
继承的形式:
[访问权限修饰符][修饰符] 子类名 extends 父类名{
子类体
}
继承具有传递性:
C类从B类继承,B类又从A类继承,那么C类就具有B类和A类的所有非私有属性和非私有方法。
当一个没有继承任何一个类时,jvm会默认让类继承Object类 Object是 java为所有类提供的基类。
子类构造方法会先调用父类构造方法,使用super关键字调用父类任意一个构造方法,必须写在构造方法的第一行,如果子类的构造方法中没有显式地调用基类构造方法,则系统默认调用基类无参数的构造方法。
super关键字
super关键字可以用来访问父类的的成员,例如:
super.成员变量名 来引用父类成员变量。
super.方法名(参数列表) 访问父类的方法。
super.构造方法(参数列表) 访问父类构造方法
不要把super误认为是父类对象.在创建子类对象时,不会创建父类对象.,只会将父类中的信息加载到子类对象中存储。
重写(override)
当父类的方法不足以实现子类的的需求时,可以对该方法进行重写,在重写的方法前加override。
重写时我们要注意方法名字、参数、返回值类型相同,且子类重写的访问权限不能小于父类。
下面是我自己写的测试代码,其中体现了继承的特点:
public class Animal {
private String name;
private int age;
public Animal() {
System.out.println("这是Animal类的空构造方法");
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("小动物吃饭");
}
public void sleep(){
System.out.println("小动物睡觉");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void showInfo(){
System.out.println("小动物的名字叫:"+name);
System.out.println("小动物今年:"+age+"岁");
}
}
public class Dog extends Animal{
public Dog() {
System.out.println("这是Dog类的无参构造方法");
}
public Dog(String name, int age) {
super(name, age);
System.out.println("这是Dog类的有参构造方法");
}
public int play(){
System.out.println("狗会玩");
return 4;
}
}
public class Cat extends Animal{
public Cat() {
System.out.println("这是Cat类的无参构造方法");
}
public Cat(String name, int age) {
super(name, age);
System.out.println("这是Cat类的有参构造方法");
}
public void jump(){
System.out.println("猫跳的很高");
}
}
public class xiaotianquan extends Dog{
public xiaotianquan() {
System.out.println("这是xiaotianquan类的无参构造方法");
}
public xiaotianquan(String name, int age) {
super(name, age);
System.out.println("这是xiaotianquan类的有参构造方法");
}
public void eat(){
System.out.println("哮天犬吃肉肉");
}
public void fly(){
super.eat();
this.eat();
System.out.println("哮天犬会飞");
}
@Override
public int play() {
System.out.println("哮天犬飞来飞去");
return super.play();
}
}
public class TestAnimal {
public static void main(String[] args) {
Dog dog=new Dog();
dog.setAge(7);
dog.setName("小狗");
dog.showInfo();
dog.sleep();
dog.eat();
dog.play();
System.out.println();
Cat cat=new Cat();
cat.setName("小猫");
cat.setAge(4);
cat.showInfo();
cat.jump();
cat.eat();
cat.sleep();
System.out.println();
xiaotianquan xtq=new xiaotianquan();
xtq.setName("哮天犬");
xtq.setAge(9999);
xtq.showInfo();
xtq.fly();
xtq.eat();
xtq.play();
System.out.println();
xiaotianquan xiaotianquan =new xiaotianquan("老哮天犬",200000);
xiaotianquan.eat();
xiaotianquan.showInfo();
xiaotianquan.fly();
}
}
运行结果:
这是Animal类的空构造方法
这是Dog类的无参构造方法
小动物的名字叫:小狗
小动物今年:7岁
小动物睡觉
小动物吃饭
狗会玩
这是Animal类的空构造方法
这是Cat类的无参构造方法
小动物的名字叫:小猫
小动物今年:4岁
猫跳的很高
小动物吃饭
小动物睡觉
这是Animal类的空构造方法
这是Dog类的无参构造方法
这是xiaotianquan类的无参构造方法
小动物的名字叫:哮天犬
小动物今年:9999岁
小动物吃饭
哮天犬吃肉肉
哮天犬会飞
哮天犬吃肉肉
哮天犬飞来飞去
狗会玩
这是Dog类的有参构造方法
这是xiaotianquan类的有参构造方法
哮天犬吃肉肉
小动物的名字叫:老哮天犬
小动物今年:200000岁
小动物吃饭
哮天犬吃肉肉
哮天犬会飞
Process finished with exit code 0
抽象类
抽象类的概念:
如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。 抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法。 用abstract修饰的类就是抽象类。如果某个类中包含有抽象方法,那么该类就必须定义成抽象类。
抽象类的特点:
抽象类不能被实例化,但可以有构造方法,因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。 抽象类只能用作基类,表示的是一种继承关系。继承抽象类的非抽象类必须实现其中的所有抽象方法,而已实现方法的参数、返回值要和抽象类中的方法一样。否则,该类也必须声明为抽象类。
抽象方法
抽象方法是一种特殊的方法:它只有声明,而没有具体的实现。抽象方法必须用abstract关键字进行修饰。