黑马程序员——JAVA基础之面向对象(下)
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
上篇博客讲述了面向对象三大特征之一的封装,接下来将讲述省下的继承,多态以及其他的一些知识点。
一、面向对象中的static
static是一个修饰符,用来修饰成员变量以及成员函数。被修饰的成员的数据将不再存放在堆内存中,而转移到方法区中,并且所有对象都指向同一个值。而且不需要对象,直接用类名就能使用这个成员。一下代码将演示static的一些特性:
class student { int age; String name; static String country = "CN";//使用static关键字修饰成员变量 } public class Test { public static void main(String[] args) { System.out.println(student.country);//使用类名调用被static修饰的变量 student s1= new student(); System.out.println(s1.country); //使用对象调用变量 student.country = "a"; //修改被static修饰的变量 System.out.println(s1.country); //修改完后输出 }
输出结果为” CN CN a“,可以发现当改变了被stiati修饰的country的值后对象的值也被改变了。
二、类的继承
类的继承是面向对象的另一大特征,继承能提高代码的复用性,能让类与类之间产生关系,有了这个关系,才有了多态的特征。接下来将用代码演示继承的基本使用方法。
class A{ //定义一个基类 int num =1; void show(){ System.out.println(num); } } class B extends A{ //定义一个类仅继承A,其余不写任何内容 } public class Test { public static void main(String[] args) { B b = new B();//实例化子类B b.show();//虽然B类可以使用父类A中的方法 } }
虽然B类并没有内容,但是由于继承了A类,可以调用A类中所有成员变量以及方法,运行show方法将在控制台打印“1”。需要注意的是java只支持单继承,不支持多继承。不过java可以多层继承,也就是说可以定义一个C类来继承B类,也可以调用A类中所有成员变量以及方法,就不用代码演示了。
说完基本的继承应用接下来说说复杂点的,如果子类中出现和父类一样名字的变量、函数以及都有构造函数改如何区分呢?若子类与父类中成员变量拥有同样的变量名,则在子类中若想调用父类的变量内容需要添加super关键字,若想调用本身的变量则可添加this关键字或不添加,下面用代码演示:
class A{ //定义一个基类 int num =1; } class B extends A{ int num = 2;//定义一个类来继承A类,且与父类有一个相同变量名但内容不同的变量 void show(){ System.out.println(super.num);//添加suoer关键字将输出父类中的内容 System.out.println(num);//不添加关键字将输出子类中的内容 System.out.println(this.num);//添加this关键字将输出子类中的内容 } } public class Test { public static void main(String[] args) { B b = new B(); b.show(); } }
输出结果为“1 2 2”。
若子类与父类中函数拥有相同的函数名且入参相同时,子类会覆盖父类的函数,称之为重写,若在子类中想调用父类中的函数与调用变量一样需要添加super关键字,由于与调用变量内容大致相同,就不演示了。
若子类与父类都有构造函数,则在对子类对象进行初始化,父类的构造函数也会运行,那是因为子类的构造函数默认第一行有一条隐式的语句super(),super()会访问父类空参数的构造函数,而且子类中所有的构造函数默认第一行都是super()。之所以默认第一行是为了查看父类如何进行数据初始化的,以便子类可以在构造函数内调用父类的变量。请看代码演示:
class A{ //定义一个基类 A(){ //定义一个空入参的构造函数 System.out.println("A"); } A(int X){ //定义一个带有入参的构造函数 System.out.println("X"); } } class B extends A{ //定义一个类来继承A B(){ //由于继承了A所以这里其实隐藏了一行super();作用是调用父类空入参的构造函数 System.out.println("B"); } } public class Test { public static void main(String[] args) { B b = new B(); } }以上代码输出结果为“A B”。也就是说实例化子类B时先运行了父类A中的空的构造函数再运行子类本身的构造函数,并不会运行带有入参的构造函数。
三、抽象类
在java中被abstract关键字修饰的方法没有方法体,该方法的实现由子类完成,称之为抽象方法,包含抽象方法的类就是抽象类。抽象类不可以被实例化,也就是不可以用new创建对象。抽象类需要通过子类来实例化,子类必须实现父类所有抽象的方法。下面演示抽象方法基本应用:
abstract class person { //定义一个抽象类 private String name; private String age; abstract void say();//拥有一个未实现的方法,也就是抽象方法 } class Chinese extends person{ //定义一个类来继承抽象类 @Override void say() { //子类继承抽象类必须实现所有抽象方法 System.out.println("你好"); } } class American extends person{ //同上 @Override void say() { System.out.println("hello"); } } public class Test { public static void main(String[] args) { Chinese a = new Chinese();//抽象类需要通过子类来实例化 a.say();//调用say方法 American b = new American();//同上 b.say(); } }输出结果为“你好 hello”。
四、接口
接口可以被认为是一个特殊的抽象类。如果抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。接口使用interface来表示,子类中用implements实现。接口中变量默认添加修饰符[public]、[static]、[final],方法默认添加修饰符[public]、[abstract]。
接口与类有几点不同:1、接口可以用来多实现。这也是对多继承不支持的转换形式。java支持多实现。2、类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。3、接口与接口之间可以有继承关系。而且可以多继承。下面用代码演示下简单应用:
interface A{ //定义一个接口 int NUM =30;//相当于public static final int NUM = 30 void a(); ////相当于public abstract a() } interface C{ //定义另一个接口 String name ="张三"; } class B implements A,C{ //定义一个类来多实现接口A和C @Override public void a() { //实现家口必须实现接口内所有抽象方法 System.out.println(name);//由于实现了C接口,所以可以使用name常量 } } public class Test { public static void main(String[] args) { B b = new B(); b.a();//将在控制台打印“张三” } }
五、类的多态
面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。多态是指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。多态能够消除类型之间的耦合关系。
函数的多态有两种表现形式:重载和覆盖。
重载(overload),是发生在同一类中。与什么父类子类、继承毫无关系。标识一个函数除了函数名外,还有函数的参数(个数和类型)。也就是说,一个类中可以有两个或更多的函数,叫同一个名字而他们的参数不同。下面用例子演示重载
class A { 3ff7 //定义一个类,含有两个入参不同方法名相同的方法 public void show(int X){ } public void show(String Y){ } }覆盖(override),是发生在子类中,也就是说必须有继承的情况下才有覆盖发生。我们知道继承一个类,也就有了父类了全部方法,如果你感到哪个方法不适用,功能要变,那就把那个函数在子类中重新实现一遍。这样样再调用这个方法的时候,就是执行子类中的过程了。父类中的函数就被覆盖了。
class A { public void show(int X){ System.out.println("A and X"); } } class B extends A{ //定义一个类继承A,重写方法show public void show(int X){ System.out.println("B and X"); } }对象的多态性:父类 X = new 子类(),子类转型成父类是向上转型,反过来说,父类转型成子类就是向下转型。也就是说:子类 Y = (子类) new 父类()。接下来将用代码演示:
abstract class person{ //定义一个person抽象类,拥有抽象方法want String name; int age; abstract void want(); } class student extends person{ //定义一个类来继承person类 void learning(){ //定义一个子类独有的方法 System.out.println("成绩提升"); } void want(){ //实现所有父类中的抽象方法 System.out.println("想要成绩"); } } public class Test { public static void main(String[] args) { person a = new student();//此为向上转型 a.want(); //此时无法调用student内独有的方法a.learning() student b = (student) a;//此为向下转型 b.learning();//可以调用子类独有的方法 } }
- 113_面向对象(异常声明throws)_黑马程序员_Java基础视频
- 黑马程序员,Java基础知识三:面向对象
- 黑马程序员————java基础--------二维数组及面向对象(一)
- 黑马程序员——Java基础---面向对象(封装、继承、多态)
- 黑马程序员---java基础---2面向对象
- 黑马程序员_Java基础02_面向对象
- 黑马程序员——Java基础---面向对象
- 黑马程序员——Java基础——面向对象
- 黑马程序员——Java基础---面向对象
- 黑马程序员 Java基础<三>--->面向对象
- 黑马程序员——Java基础--面向对象(1)
- 黑马程序员——Java基础---面向对象(一)
- 黑马程序员------Java基础学习------面向对象(下)
- 黑马程序员-java基础(四)-面向对象(封装、继承、多态)
- 黑马程序员-Java语言基础–面向对象 第10天
- 黑马程序员————java基础之面向对象
- 黑马程序员_Java基础_面向对象(内部类、异常1)
- 黑马程序员——java基础---面向对象(一)
- 黑马程序员——JAVA基础----面向对象
- 114_面向对象(多异常处理)_黑马程序员_Java基础视频