作者:钟良堂
经过上周对Java面向对象的初步学习,我们已经初步了解了Java中面向对象的三个基本特性,下面我们一起来深入了解面向对象的具体内容吧!
一:继承性
继承性是java面向对象中的特性。而继承性最为关键的地方为:代码重用性的问题,利用继承性可以从已有的类中继续派生出新的子类,也可以利用子类扩展出更多的操作功能。
继承性的实现代码为:class 子类 extends 父类{ }
有以下3点说明:
1、对于extends而言,需要不断的开展开来,但是为了理解上的方便,这些统一称之为:继承;
2、子类又称之为派生类;
3、父类又称之为超类(Super class);
以下代码为子类继承父类的属性及方法
class Person{
private String name;
private int age;
public Person() {}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
}
}
class Student extends Person {
private String school;
public void setSchool(String school){
this.school = school;
}
public String getSchool(){
return this.school;
}
}
public class School{
public static void main(String args[]){
Student stu = new Student();
stu.setName("zhangsan");
stu.setAge(123);
stu.setSchool("大学");
System.out.println("名字" + stu.getName() + ",年龄" + stu.getAge()+ stu.getSchool());
}
}
从这中间可以得到以个结论:
子类在实际中的运用中,是将父类定义得更加具体化的一种手段。
在继承的使用中,有三大限制,这些在实际的运用及编写代码的时候需要多加注意:
一、继承不可以多重继承,但是可以多层继承。
子类与父类的使用如下:
class A{
public void fun(){
System.out.println("这就是A");
}
}
class B extends A{
public void fun(){
System.out.println("这就是B");
}
}
class C extends A{
public void fun(){
System.out.println("这就是C");
}
}
class New1{
public static void main(String args[]){
B b1 = new B();
b1.fun();
C c1 = new C();
c1.fun();
}
}
二、在子类在继承父类时,严格来说会继承中,但是在父类多有的私有操作属于中称之为隐形继承。所有的非私有操作属于显示属性。
class A {
private String msg;
public void setMsg(String msg) {
this.msg = msg;
}
public String getMsg() {
return this.msg;
}
}
class B extends A { // 继承自A类
}
public class Demo {
public static void main(String args[]) {
B b = new B();
b.setMsg("Hello"); // 设置msg属性,属性通过A类继承
System.out.println(b.getMsg()); // 通过子类对象取得msg属性
}
}
三、在子类构造前一定会默认调用父类的构造(默认使用无参构造),以保证父类的对象先实例化,子类对象后实例化。
观察实例化对象操作:
class A {
public A() { // 父类提供的无参构造方法
System.out.println("A、A类的构造方法!");
}
}
class B extends A { // B是子类继承父类A
public B() { // 定义子类的构造方法
System.out.println("B、B类的构造方法!");
}
}
public class Demo {
public static void main(String args[]) {
new B(); // 实例化子类对象
}
}
子类隐含语句:
class B extends A { // B是子类继承父类A
public B() { // 定义子类的构造方法
super() ; // 父类中有无参构造时加与不加无区别,如果编写则必须出现在首行
System.out.println("B、B类的构造方法!");
}
父类不提供无参构造方法:
class A {
public A(String title) { // 父类提供的有参构造方法
System.out.println("A、A类的构造方法,title = " + title);
}
}
class B extends A { // 定义子类B
public B(String title) { // 子类提供有参构造
super(title); // 明确调用父类构造,否则将出现编译错误
System.out.println("B、B类的构造方法!");
}
}
public class Demo {
public static void main(String args[]) {
new B("Hello"); // 实例化子类对象
}
}
方法覆写:
特产主要特征:子类可以根据父类已有的功能进行功能的扩展,但是在子类定义属性或方法时,可以出现定义的属性或方法与父类同名的情况,这样的操作成为覆写。
class A {
public void fun() { // 在父类中定义的方法
System.out.println("A类中的fun()方法。") ;
}
}
class B extends A { // 定义子类,此时没有覆写任何方法
public void fun() { // 此处为覆写
System.out.println("B类中的fun()方法。") ;
}
}
class C extends A {
public void fun() { // 此处为覆写
System.out.println("C类中的fun()方法。") ;
}
}
public class TestDemo {
public static void main(String args[]) {
B b = new B() ; // 实例化子类对象
b.fun() ; // 调用fun()方法,此时方法被覆写,所以调用被覆写过的方法
C c = new C() ; // 实例化子类对象
c.fun() ; // 调用fun()方法,此时方法被覆写所以调用被覆写过的方法
}
}
二:封装性
封装是java的面向对象的特点,
是将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
封装的优点:
1.提高代码的安全性。
2.提高代码的复用性。
3.“高内聚”:封装细节,便于修改内部代码,提高可维护性。
4.“低耦合”:简化外部调用,便于调用者使用,便于扩展和写作。
在android中 自己经常对接接口的时候使用到,比如请求接口时候写的bean 里面封装的数据,等等。
下面自己手写一个Student类 看看封装
public class Student {
private String name;
private String sex;
private int age;
private int achievement;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getAchievement() {
return achievement;
}
public void setAchievement(int achievement) {
this.achievement = achievement;
}
}
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("小牧");
stu.setSex("女");
stu.setAge(23);
stu.setAchievement(60);
System.out.println("姓名:"+stu.getName()+ "性别:"+ stu.getSex()+"年龄:"+ stu.getAge()+"分数:"+stu.getAchievement());
}
}
3:多态性
多态性的解释:
1.子类对象的多态性,父类的引用指向子类对象
2.虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际上执行的是子类重写父类的方法
多态性的前提:
1,要有类的继承性.
2,要有子类对父类的方法的重写
注意点: 程序分为编译状态和运行状态,
对于多态性来说,编译时,“看左边”,将此引用变量理解为父类的类型
运行时,“看右边”,关注于真正对象的实体(子类的对象),那么执行的方法就是子类重写的;
下面据一些例子:
package text1;
public class Test {
public static void main(String[] args) {
Person P=new Student();//这个就是多态性的使用
P.eat();//这个会执行Student类对应的eat方法。
/*下面介绍多态性中向下转换的例子,比如你直接调用Student类中特有的studying是不可以的,要想调用,你得将其转换为
Student类,即下面的Student S=(Student)P;*/
if(P instanceof Teacher)//1
{
Teacher T=(Teacher)P;//这个编译时P是Person类,故不会报错,但在运行是会报错的
System.out.println("教师转换成功");
T.teaching();
}
if(P instanceof Student)//2
{
Student S=(Student)P;
System.out.println("学生转换成功");
S.studying();//转换之后才可以调用studying方法。
}
}
}
对应的父类Person,子类teacher,Student的代码在下面
我们来分析一些出现执行了2,而没有执行1的原因
package text1;
public class Person {
protected int age;
protected String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void eat() {
System.out.println("人吃饭");
}
public void walk() {
System.out.println("人走路");
}
package text1;
public class Teacher extends Person {
protected int age;
protected String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void eat() {
System.out.println("教师在家吃饭");
}
public void walk() {
System.out.println("教师走路慢慢");
}
public void teaching() {
System.out.println("教师要教书");
}
}
package text1;
public class Student extends Person{
protected int age;
protected String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void eat() {
System.out.println("学生在食堂吃饭");
}
public void walk() {
System.out.println("学生走路匆匆");
}
public void studying() {
System.out.println("学生要学习");
}
}