黑马程序员——java基础---面向对象(二)
来源:互联网 发布:w两个世界知乎 编辑:程序博客网 时间:2024/05/18 03:38
面向对象(二)
一、继承。
1、继承概述。
请先看一个例子:在现实生活中,人们有各种各样的分类,比如有的人是学生,有的人是教师,有的人是工人......这些都是现实世界可以存在的事物,而具体到某一个人则是该事物的对象了。但是我们发现,在这么多的类中,它们都有一种共性和联系——它们都是人。
所谓继承,就是当多个类中存在相同的属性和行为时,将这些属性和行为单独提取出来构成一个类,那么多个类都无需再定义这些属性和行为,而只需要继承单独的那个类。多个类可以称其为父类,单独的这个可以叫做父类或者超类,子类可以访问父类中的非私有属性和行为。
子类是通过关键字extends产生与父类的关系的,例:
package com.itheima;class Person{private String name;private int age;Person(String name,int age){this.age=age;this.name=name;}}class Student extends Person{private int studentidcard;Student(String name,int age,int studentidcard){super(name,age);this.studentidcard=studentidcard;}}那么继承的出现有什么好处呢?
继承出现提高了代码的复用性,而且让类与类之间产生了联系,为多态提供了前提。但是,注意千万不要单纯的为了代码的复用性来使用继承,子类和父类之间一定要有逻辑上的继承关系才能使用继承。
2、继承的特点。
在java体系当中,它只支持单继承,不支持多继承。因为多继承容易带来安全问题,当多个父类定义了相同的功能,但是功能内容不同时,子类对象不确定调用哪一个,但是java中保留这种多继承机制,在这里称之为多实现。
class Student extends Person//rightclass Student extends Person,HeiMa//Error在java体系中还支持多层继承——C继承了B,B继承了A,这样就构成了一个继承体系,在javaapi中这是最常见的现象,将一个个有共同属性和行为的事物抽象作为其继承类,然后将该继承类再抽象变成最根本的抽象类(一般都会成为接口)。
class Personclass Student extends Personclass HeiMaStudent extends Student如上,Person类是这个继承体系的最上级类,然后一层一层的被继承下来,到现实中的具体事物。
在javaapi中经常遇到这样的继承体系,我们如何使用它呢?
要想使用体系,先查阅体系的父类描述,因为父类中定义了该体系中的共性功能。通过了解共性功能,我们就可以知道该体系的基本功能,然后这个体系基本上就可以使用了。注意:在具体调用时,要创建最子类的对象,这是因为体系中的父类基本上都是抽象类和接口,不能创建对象,而且子类对象有父类所没有的独特功能。
package com.itheima;class Person{ void show() { System.out.println("这是一个最上级类-人"); }}class Student extends Person{void show() { System.out.println("我继承了人,我是人中的学生"); }}class HeiMaStudent extends Student{void show() { System.out.println("我继承了学生,我现在是黑马训练营的学生啦!"); }}public class ExtendsDemo {public static void main(String[] args){HeiMaStudent s1 = new HeiMaStudent();s1.show();}}
3、super关键字和继承后成员特点
super关键字和this关键字相对应。
this代表本类引用,super代表父类引用。
当子父类出现后,类成员的特点:
成员变量的特点:
如果子父类中出现了同名的非私有成员变量,子类访问本类中变量用this,要访问父类变量则用super,父类中的私有变量是没办法被子类访问的。
package com.itheima;class Student {int x=4;void show() { System.out.println("我继承了人,我是人中的学生"); }}class HeiMaStudent extends Student{int x=5;void showHeiMa() { System.out.println("我继承了学生,我现在是黑马训练营的学生啦!"+"我要求我的父类的x"+super.x); }}public class ExtendsDemo {public static void main(String[] args){HeiMaStudent s1 = new HeiMaStudent();s1.showHeiMa();System.out.println(s1.x+"-----"+s1.x);//注意,用对象。的方式调用成员变量只能是子类的对象。}}
子父类成员函数的特点:
package com.itheima;class Student {int x=4;void show() { System.out.println("我继承了人,我是人中的学生"); }}class HeiMaStudent extends Student{int x=5;void show()//该函数会覆盖Student类中的show()方法! {super.show(); System.out.println("我继承了学生,我现在是黑马训练营的学生啦!"+"我要求我的父类的x"+super.x); } void show(int x)//这个就是函数的重载了!<span style="white-space:pre"></span>{<span style="white-space:pre"></span>this.x=x;<span style="white-space:pre"></span>}}public class ExtendsDemo {public static void main(String[] args){HeiMaStudent s1 = new HeiMaStudent();s1.show();System.out.println(s1.x+"-----"+s1.x);//注意,用对象。的方式调用成员变量只能是子类的对象。}}子父类构造函数的特点:
package com.itheima;class Student {String name;;int age;Student(String name ,int age){this.age=age;this.name=name;}void show() { System.out.println("这个人的属性有:"+name+","+age); }}class HeiMaStudent extends Student{int studentid;HeiMaStudent(String name,int age,int studentid){super(name,age);//此处一定要定义父类构造函数,因为父类没有默认构造空函数this.studentid=studentid;}void show()//该函数会覆盖Student类中的show()方法! {super.show(); System.out.println("我现在是黑马训练营的学生啦!我的属性有"+age+","+name+","+studentid); }void show(String name)//这个就是函数的重载了!{super.name=name;//此处修改父类的成员也就是修改子类的成员!System.out.println("我现在是黑马训练营的学生啦!我的属性有"+age+","+this.name);//在子类中调用父类的成员(该成员不和子类的重名)的时候使用this和super是一样的。}}public class ExtendsDemo {public static void main(String[] args){HeiMaStudent s1 = new HeiMaStudent("张三",22,20141121);s1.show();s1.show("李四");}}
4、final关键字
3、被final修饰的成员函数不能被复写
package com.itheima;public class FinalDemo { public static void main(String[] args) { Demoer dm = new Demoer(); dm.show(); }}class Demoer{final String x = "张三";//只能赋值一次 public final void show() { System.out.println("这个成员函数是无法被复写的"); final class Inner//无法被继承 { int x=2; public void inDemo() { System.out.println(x+","+this.x+","+Demoer.this.x); } } Inner i=new Inner(); i.inDemo(); }}
5、抽象类
package com.itheima;public class AbstractDemo {}abstract class Process{ abstract public void konwCustomerIdea();//作为一个程序员,要编程首先要了解用户需求 abstract public void designAlgorithm();//设计算法 abstract public void makeprocess();//开始编程 abstract public void deBugging();//调试程序 public void startDesignPrecess() { this.konwCustomerIdea(); this.designAlgorithm(); this.makeprocess(); this.deBugging(); }}class Myprocess extends Process{ public void konwCustomerIdea() {} public void designAlgorithm() {} public void makeprocess() {} public void deBugging() {}}
6、模板设计模式。
在定义功能的时候,有一部分是确定的,这些方式可以定义成一个类的方法,但是有一些是不确定的,那么我们就定义这个不确定的成一个抽象方法,该类也编程了抽象类,这样,在使用其子类的时候复写那些不确定的方法就完整描述了整个事物
package com.itheima;public class AbstractDemo {public static void main(String[] args){MyProcess mp=new MyProcess();mp.startDesignPrecess();}}abstract class Process{abstract public void konwCustomerIdea();//作为一个程序员,要编程首先要了解用户需求abstract public void designAlgorithm();//设计算法abstract public void makeprocess();//开始编程abstract public void deBugging();//调试程序public void startDesignPrecess(){this.konwCustomerIdea();this.designAlgorithm();this.makeprocess();this.deBugging();}}class MyProcess extends Process{public void konwCustomerIdea() {System.out.println("开始了解用户的需求!");}public void designAlgorithm() {System.out.println("开始设计算法!");}public void makeprocess(){System.out.println("开始编写程序!");}public void deBugging() {System.out.println("开始进行程序调试!");}}
如以上代码,这就是一个典型的模板设计模式,所谓模板就是我们已经了解到的这一部分方式,这些方式一般来说就是做某些事的一些流程,而这些流程的某一步具体怎么做我们不确定,这样就可以定义一个抽象方法来描述,然后在子类中复写这些流程的具体步骤,这样就完整的表述了该事物。
7、接口。
接口就是一个抽象类,该抽象类内部全是抽象方法。
接口用interface定义,class定义类
接口定义时需要注意以下问题:接口中常见定义的是成员常量和抽象方法。
定义成员常量格式为:public static final;定义抽象方法格式为:public abstract
接口中的所有成员都是public的,这是为了让这些成员都能被继承,函数被复写。
接口的特点:接口是对外暴露的规则,是对程序功能的扩展,程序多一个接口就多了若干可以复写的功能,充实了程序的功能性。
接口是用来多实现的,一个类可以实现多个接口,这就是java中的“多继承”,用implements关键字来实现。
接口和接口之间是可以继承的!
二、多态
1、概述
在现实生活中,总有那么一些事物有多重形态。例如:动物中的猫和狗,猫这个事物建立对象可以是猫 cat = new 猫();同时,猫也是动物的一种,所以也就可以这样定义:动物 cat=new 猫();其中动物明显是猫的父类。所以,所谓多态,就是父类的引用指向了子类对象。
要实现多态,很明显的需要类和类之间存在继承或者类和接口之间存在实现关系,而且必须存在覆盖操作。
多态有很多好处:它大大提高了程序的扩展性,但是只能使用父类引用调用父类的成员。
public class DuoTaiDemo {public static void main(String[] args){Animal cat = new Cat();Animal ani = new Animal();Cat c=new Cat();cat.show();ani.show();c.show();}}class Animal{public void show(){System.out.println("这是一个动物!");}}class Cat extends Animal{public void show(){System.out.println("这是一只猫!");}}
2、在多态中如何让父类引用来调用子类中特有方法。
我们知道,在多态中,可以让父类引用调用子类中覆盖了父类的方法,这也是多态最常见的引用,但是当我们需要调用子类特有的方法的时候,该怎么办呢?
这时,我们需要将该多态的类型转换成子类类型,比如,对动物 cat = new 猫();来说我们需要调用cat对象的特有方法,就需要猫 cat1=(猫)cat,这时强制类型转换!
package com.itheima;public class DuoTaiDemo {public static void main(String[] args){Animal cat = new Cat();Animal ani = new Animal();Cat c=new Cat();cat.show();ani.show();c.show();show(cat);}public static void show(Animal a){a.show();}}class Animal{public void show(){System.out.println("这是一个动物!");}}class Cat extends Animal{public void show(){System.out.println("这是一只猫!");}}
3、多态的特点
在成员函数来说:编译时,参阅引用类型的类中是否有此函数,若有则编译通过;在运行时则是运行子类的函数。
在变量来说:不论编译还是运行时都是查阅的引用类型的类成员。
在静态成员变量来说:不论编译还是运行都是查阅引用类型的类的静态成员。
package com.itheima;abstract class Fu{int x=3;abstract public void show();public static void show1(){System.out.println("这里一个父类的静态方法");}}class Zi extends Fu{ int x=4;public void show(){System.out.println("这是一个子类");}public static void show1(){System.out.println("这里是子类中的静态方法!");}}public class DuoTai2 {public static void main(String[] args){Fu z=new Zi();System.out.println("x="+z.x);//这里调用到的是x=3z.show();//这里调用的是子类的show()方法,被复写了z.show1();//这里调用的是父类的静态方法。}}
三、内部类
1、概述。
内部类就是在一个类的内部在定义一个类,在描述一个现实事物中,若它内部还有事物,则用内部类来描述,因为内部事物使用了外部事物的内容。它也被叫做嵌套类或者内置类,它的访问特点是:内部类可以直接访问外部类成员,之所以能够直接访问外部类对象是因为内部类有一个外部类的引用——外部类名.this,而外部类要访问内部类则需要在外部建立对象。
2、访问格式。
当内部类定义在类的成员位置时:
如果不是私有化的,则可以再外部其他类中直接建立内部类对象,其格式为:Outer.Inner in=new Outer().new Inner();
如果被static和private修饰
被private修饰,则内部类只能在外部类中建立对象,被外部类所封装。
被static修饰,整个类存在于方法区中,则内部类中只能访问外部类的静态成员,访问权限受到限制。此时,在外部其他类中可以直接访问该内部类静态成员:Outer.Inner.function();也可以访问该静态内部类的非静态成员:new Outer.Inner() ;
注意:静态函数内部一定是静态的,但是静态内部类内部有静态的也有非静态的!
当内部类定义在局部位置时:它依然能够直接访问外部类成员,因为它的外部类名.this引用依然存在,但是它只能访问带有final修饰的局部变量。
package com.itheima;class Outer{int x=3;static int y=2;class Inner1{int x=4;public void show(){int x=5;System.out.println(Outer.this.x+","+this.x+","+x);//5,4,3}}static class Inner2//不能访问外部内的非静态成员{int z=1;public void show(){System.out.println(Outer.y+","+this.z);}public static void show1(){System.out.println(Outer.y);}}}public class InnerDemo {public static void main(String[] args){Outer.Inner1 in = new Outer().new Inner1();//非私有定义在成员位置上,在其他外部类中创建内部类对象in.show(); new Outer.Inner2().show();//成员位置上的静态内部类访问非静态成员 Outer.Inner2.show1();//成员位置上的静态内部类访问静态成员}}
3、匿名内部类。
匿名内部类其实就是内部类的简写格式,它的使用前提是它必须继承了一个类或者实现了一个接口。
它的格式是:new 父类或者接口名(){定义子类的内容}。
匿名内部类就是一个子类对象,可以理解为带内容的对象,这个对象有些胖。
注意:匿名内部类中子类内容最好不要超过三个成员函数,不然阅读性非常的差。
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
- 黑马程序员——java基础---面向对象(二)
- 黑马程序员——Java基础---面向对象(二)
- 黑马程序员——Java基础---面向对象<二>
- 黑马程序员——java基础-面向对象(二)
- 黑马程序员——Java基础-------面向对象(二)
- 黑马程序员——Java基础---面向对象(二)
- 黑马程序员-----Java基础----面向对象(二)
- 黑马程序员—java面向对象二
- 黑马程序员 java基础<—>--->面向对象
- 黑马程序员——Java基础---java面向对象基础
- 黑马程序员——面向对象基础(二)
- 黑马程序员——java基础--面向对象基础
- 黑马程序员————java基础---------面向对象(二)
- 黑马程序员————Java基础之面向对象(二)
- 黑马程序员——java基础——面向对象(二)
- 黑马程序员——Java基础——面向对象的特征(二)
- 黑马程序员——java基础--面向对象(篇二)
- 黑马程序员——java基础----面向对象(二) 继承和多态
- Android心得4.3--SQLite数据库--execSQL()和rawQuery()方法
- poj 3253 Fence Repair【哈夫曼树、优先队列】
- 杨辉三角
- 用wpa_cli 连接无线网络
- SDUT 2543 ——整除 容斥原理
- 黑马程序员——java基础---面向对象(二)
- Android Activity的launchMode
- javascript获取当天、本周、本月、本年 开始及结束时间
- Java多线程相关知识
- 代码转换工具(as3 - cocos2dx) (二) 语言总体分析
- ARCGIS部分刷新
- 办公系统中MS Word文件转换为PDF技术方案
- 构建高并发高可用的电商平台架构实践
- android:versionCode和android:versionName 用途