首先,Java面向对象的三大特征:
三大特征:
▪ 封装
▪ 继承
▪ 多态
首先面向对象的第一个特性 封装 :
封装:就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
我们提到封装就必须提到几个修饰符的作用域:
上图我们在面向对象的基础里面也提到过,而我们常用的修饰符一般是:public,这个修饰符相信大家已经很熟悉了,这个修饰符的作用域是所有,我在这个包里面用public申明的类和熟悉在其他包里面照样可以访问。另一个就是private,这个代表私有的,私人的,用这个申明的类、属性、方法只要出了这个类是无法被访问的,哪怕是在这个包内同样无法访问。
例如:
private int age;
此时的属性age只能在此类里面访问,出了这个类以后就无法被访问。
被封装以后怎么给这个属性赋值和获取这个值:
赋值:在类里面写一个共有的(public)方法,因为在同一个类中所以这个方法可以赋值和获取到私有的属性和方法;
private int age;
//给age赋值
public void setage(){
age = ?;
}
//打印出age的值
public void getage(){
System.out.println(age);
}
因为setage和getage是共有类型的,在不同的类和包下都可以访问,就可以间接的对age属性进行赋值和访问。
然后面向对象的第二个特性 继承 :
因为类具有的属性,此类所创造的对象都具有本属性,所以要使用继承的话,就必须有个父类。
要使用继承就要先创造一个父类:
然后新建一个子类:
继承机制是允许并鼓励类的重用的;派生类也可以被继承,成为父类,即派生类既具有从父类中继承下来的属性和行为,又具有自身新定义的属性和行为,当派生类又被它的子类所继承时,那么它所继承的及自身所定义的属性和行为也被下一级子类所继承下去Java语言中只支持单继承,即一个子类只继承自一个父类。Java语言中可以通过接口的方式来弥补由于不支持多继承而带来的子类不能使用多个父类的属性和行为所产生的不足。
子类访问父类的属性和方法:
super(); //访问构造类
super(name); //访问一个参数的构造类
super.name; //访问一个属性(name)
super.print(); //访问print方法
super注意事项:super只能出现在子类的方法和构造方法中;super调用构造方法时,只能是第一句;super不能访问父类的private成员。
不能被继承的父类元素:
private成员
子类与父类不在同包,使用默认访问权限的成员
构造方法
关于多重继承的初始化顺序:
一个继承实例:
父类:
1 package Dome; 2 3 public class Dome1 { 4 public String name; 5 public int age; 6 public char sex; 7 8 /** 9 * 创造一个类后,如果不创建构造方法 10 * 那么系统会自动创建一个无参的构造方法并且无返回值和方法体 11 * 如果创造了构造方法,就会把系统默认的构造方法给掩盖 12 */ 13 public Dome1() { 14 System.out.println("无参的构造方法"); 15 // 申明一个无参的构造方法 16 } 17 18 public Dome1(String name, int age, char sex) { 19 // 申明一个含有三个参数的构造方法 20 this.name = name; 21 this.age = age; 22 this.sex = sex; 23 System.out.println(""); 24 } 25 26 public Dome1(String name) { 27 /** 28 * 申明一个只含有一个参数的构造方法 因为含有一个参数, 29 * 所以无法对其他属性赋值 所以给age,sex设置一个默认值 30 */ 31 this.name = name; 32 this.age = 10; 33 this.sex = '男'; 34 } 35 36 public Dome1(int age) { 37 /** 38 * 同样是只有一个参数的构造方法,原理和上面那个一样; 39 * 但是参数的类型不一样或者录入的参数位置不一样的话就是不一样的方法,这就是方法的重载 40 * 例如:public Dome1(String name, int age, char sex) {} 41 * public Dome1(int age, char sex, String name) {} 42 * 这两个方法他们只有录入的参数不一样,这就是方法的重载 43 * 方法的重载指的是方法名,方法的返回类型,方法的修饰符相同而参数不同的方法; 44 * 如果都相同的话那就是申明了两个一样的方法,这样会报错; 45 */ 46 this.name = "张三"; 47 this.age = age; 48 this.sex = '男'; 49 } 50 51 // 申明一个显示信息的方法 52 public void showmy() { 53 System.out.println("名字:" + name); 54 System.out.println("年龄:" + age); 55 System.out.println("性别:" + sex); 56 } 57 58 //父类熟悉和方法创造完成 59 }
子类 :
1 package Dome; 2 3 /** 4 * 创造一个子类Dome2 5 * 继承父类Dome1 6 * @author Administrator 7 * extends便是继承的关键字,后面接父类的名字,只能继承一个父类 8 */ 9 public class Dome2 extends Dome1 { 10 public int height; 11 //创造一个子类的熟悉 12 13 /** 14 * 如果父类中有无参的构造方法 15 * 那么子类默认调用父类无参的构造方法 16 * 如果父类中只有有参的构造方法,那么子类必需创建一个构造方法并且调用父类的有参构造方法并传入参数; 17 */ 18 19 public Dome2 (String name,int age,char sex,int height){ 20 /** 21 * super()调用子类的构造方法 22 * 如果我只传入一个参数那么就调用父类中只有一个参数并且参数类型一样的构造方法; 23 * 例如:super(15),那么他会调用父类中的public Dome1(int age) {}这个方法 24 * 调用方法是可以选择录入参数,或者是直接赋值 25 * 但是一个构造方法中只能调用一个构造方法,而且构造方法只能写在方法体首行 26 */ 27 super(name, age, sex); 28 //super("张三",15,'男'); 29 this.height = height; 30 } 31 32 public void showmy(){ 33 /** 34 * 同样是一个显示信息的方法,但是这个方法已经在父类中已经创造过了 35 * 而子类继承父类的所以属性和方法,在创造这个方法有什么意义 36 * 这就是方法的重写,重写父类中的方法,方法重写在行号前面会有个箭头指向父类 37 * 方法重写的意义在于,我用子类调用这个方法是,如果子类重写了这个方法就会调用子类中的这个方法 38 * 如果子类没有重写这个方法,那么就会调用父类中的这个方法 39 */ 40 //super指的父类 this指的自己 41 super.showmy();//调用父类中的显示自己信息的方法 42 System.out.println("身高:"+height); 43 } 44 }
测试类:
1 package Dome; 2 /** 3 * 测试方法 4 * @author Administrator 5 * 6 */ 7 public class Test { 8 9 public static void main(String[] args) { 10 //Dome2 dome = new Dome2(); 11 //因为子类里面已经只创造了一个有参的构造方法,所以他调用的是子类中的含参构造方法 12 //所以不传入参数会报错 13 14 Dome2 dome = new Dome2("张三", 16, '男', 170); 15 //调用显示信息的方法 16 dome.showmy(); 17 } 18 19 }
测试结果:
重现一下上面的几个注意事项:
1.父类中没有无参构造函数时:
我们先把无参构造函数注销掉
然后子类就会直接报错,报的错就是让你创造一个含参的构造函数,因为父类没有无参构造函数,无法引用。
然后我们创造一个实例,就是一个对象
因为无参构造函数被注释掉了,所以无法调用无参构造函数。
2.把子类中的重写方法注销掉
输出打印,因为子类中没有重写显示自己信息的方法,所以他调用的就是父类中的显示自己信息的方法,父类中只输出了三个,所以只有三个。
然后面向对象的第三个特性 多态 :
将父类对象应用于子类对象的特征就是面向对象编程中多态性的体现,多态指的就是在应用程序中出现的“重名”现象。
多态性允许以统一的风格编写程序,以处理种类繁多的已存在的类及其相关类。这样既降低了维护的难度,又节省了时间
使用多态实现思路:
编写父类
编写子类,子类重写父类方法
运行时,使用父类的类型,子类的对象
继承
重写
父类引用指向子类对象