疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java封装、继承、多态 以及 super关键字和方法的重写


 

   

  封装

  权限修饰符:public 公共的,private 私有的

  封装的步骤:

  1.使用private 修饰需要封装的成员变量。

  2.提供一个公开的方法设置或者访问私有的属性

  设置 通过set方法,命名格式: set属性名(); 属性的首字母要大写

  访问 通过get方法,命名格式: get属性名(); 属性的首字母要大写

  复制代码

  1 //姓名设置器方法

  2 public void setName(String name){

  3 this.name = name;

  4 }

  5 //姓名访问器方法

  6 public String getName(){

  7 return name;

  8 }

  复制代码

  代码书写的规范:java开发中一般类成员变量(属性),都是封装起来的 。

  问题:是不是所有的属性都需要使用 set 和 get 方法?

  不一定,按照需求来定。

  封装的作用:1. 框架 2. 工具类

  封装的好处:1. 提高了数据的安全性 2. 操作简单 3. 隐藏了方法的实现。

  复制代码

  1 class Student{

  2 private String name;//成员变量被修饰之后只能在本类中进行访问了,私有的了。

  3 private String sex;//如果需要在外部进行访问,就需要访问方法了 set 和 get 方法。

  4 private int age;//需要收集,但是不公开,age 就只需要一个set方法就可以了

  5

  6 //两个参数的构造方法

  7 public Student (String name,String sex){

  8 this.name=name;

  9 if(sex.equals("男")||sex.equals("女")){

  10 this.sex = sex;

  11 }

  12 }

  13 //普通方法

  14 public void study(){

  15 System.out.println(name+"在学习");

  16 }

  17 //性别设置器方法

  18 public void setSex(String sex){

  19 if(sex.equals("男")||sex.equals("女")){

  20 this.sex = sex;

  21 }else{

  22 System.out.println("你的输入不合法,请重新输入..");

  23 }

  24 }

  25 //性别访问器方法

  26 public String getSex(){

  27 return sex;

  28 }

  29 //姓名设置器方法

  30 public void setName(String name){

  31 this.name = name;

  32 }

  33 //姓名访问器方法

  34 public String getName(){

  35 return name;

  36 }

  37 //age设置器

  38 public void setAge(int age){

  39 this.age = age;

  40 }

  41 }

  42 public class fengzhuang {

  43

  44 public static void main(String[] args) {

  45 Student star = new Student("星星","性别");//性别 是不合法的操作

  46 star.study();

  47 System.out.println(star.getSex());//性别 null

  48 }

  49 }

  复制代码

  继承

  特点:继承父类的属性和方法。 特性:方法的复写(重写) 单继承(多层继承)不是多继承,c++才是多继承一个子类N个父类。

  java 中的继承 和 OC中一样。

  继承的作用:优化代码,减少代码的重复使用

  A:B OC中继承的写法,java中如何表现继承关系,用关键字 extends 表示继承。

  继承中注意事项:

  1.不要为了继承而继承,千万不要为了节省代码,任何关系都继承,这样就不伦不类了。

  2.父类的私有成员变量是不能够被继承的。

  3.父类的构造方法是不能被继承的。

  4.父类的私有方法不能被继承。

  5.子类调用自己的构造方法时,会默认调用父类中的无参构造方法。

  6.子类不能够继承不在一个包中默认权限的成员变量。

  为什么会调用父类的构造方法?

  子类在创建对象的时候初始化父类的变量。

  技巧:毕竟这两个属性是从父类上面继承下来的,初始化交给父类会好一点。。

  super(name,sex);//一般由自己指定(定义),如果自己指定了下面的 super()就不可以调用了。

  super();//调用的是父类的构造方法

  this();//调用的是自己的构造方法

  继承代码如下:

  复制代码

  1 package 面向对象的三大特性;

  2

  3 class Person{

  4 String name;//默认权限 friendly(友好的) private、public、protected

  5 String sex;

  6 Dog dog;//人和狗建立了 关联关系 整体->部分

  7 public void eat(){

  8 System.out.println(name+"在吃饭");

  9 }

  10 }

  11

  12 //定于学生类继承父类

  13 class Student extends Person{

  14 int age;

  15 public void study(){

  16 System.out.println(name+"在学习");

  17 }

  18 }

  19

  20 public class jicheng {

  21

  22 public static void main(String[] args) {

  23 Student s = new Student();

  24 s.name = "WKL";//name 自己没有 父类有

  25 s.age = 20;//age 自己有的

  26 System.out.println(s.name+"今年"+s.age+"岁了..");

  27 }

  28 }

  复制代码

  关联关系(不是继承):

  复制代码

  1 class person{

  2 String name;

  3 String sex;

  4 Dog dog;//人和狗建立了 关联关系 整体->部分

  5 public void eat(){

  6 System.out.println(name+"在吃饭");

  7 }

  8 }

  9

  10 class Dog{

  11 String name;

  12 public void cry(){

  13 System.out.println(name+"在叫");

  14 }

  15 }

  16

  17

  18 public class jicheng {

  19

  20 public static void main(String[] args) {

  21 person star = new person();

  22 star.name = "星星";

  23 Dog dog = new Dog();

  24 dog .name = "小白";

  25

  26 star.dog = dog;//把狗这个对象 给 star的dog对象成员属性

  27 /*dog.cry();*/

  28 star.dog.cry();//星星的狗在叫

  29 star.dog = null;

  30 star.eat();

  31 }

  32 }

  复制代码

  super关键字(指向父类对象的引用空间)

  作用:

  1.当子类和父类存在同名的成员变量时,会先在子类里面找默认有一个this(this.name),可以通过super来调用父类的成员变量(super.name)。

  2.super可以用来调用父类的构造方法。

  super使用的注意的地方:

  1.用super调用父类构造方法,必须是构造方法中的第一个语句。

  2.super只能出现在子类的方法或者构造方法中。

  3.super 和 this 不能够同时调用构造方法。(因为this也是在构造方法的第一个语句)

  总结:super 和 this 的区别:

  1.代表的事物不一样:

  this:代表所属方法的调用者对象。

  super:代表父类对象的引用空间。

  2.使用前提不一致:

  this:在非继承的条件下也可以使用。

  super:只能在继承的条件下才能使用。

  3.调用构造方法:

  this:调用本类的构造方法。

  super:调用的父类的构造方法

  方法的复写(重写)

  作用:父类的方法满足不了子类的实现,这个时候就需要通过复写(重写)方法再实现父类的行为。

  方法的复写使用注意事项:

  1.方法重写的时候,必须存在继承关系。

  2.方法重写的时候,方法名和形式参数 必须跟父类是一致的。

  3.方法重写的时候,子类的权限修饰符必须要大于或者等于父类的权限修饰符。( private < protected < public,friendly < public )

  4.方法重写的时候,子类的返回值类型必须小于或者等于父类的返回值类型。( 子类 < 父类 ) 数据类型没有明确的上下级关系

  5.方法重写的时候,子类的异常类型要小于或者等于父类的异常类型。

  方法的重载:方法名是一样的,只是参数列表的个数,类型,顺序不一样。

  多态(一个对象同种类型不同表现形态)

  父类的引用类型变量指向子类的对象。

  接口的引用类型变量指向类的实现。

  多态使用注意事项:

  1.多态情况下,父类 和 子类存在同名的成员变量,无论是静态的还是非静态的变量,默认访问的是父类中的成员变量。

  2.多态情况下,父类 和 子类存在同名的非静态方法,访问的是子类的非静态方法。

  3.多态情况下,父类 和子类存在同名的静态方法,访问的是父类的静态方法。

  4.多态情况下,不能访问子类特有的属性、方法。

  5.多态满足的条件:必须要有继承关系。

  总结:多态情况下,子类 和 父类如果存在同名的成员,访问的都是父类,除了同名的非静态变量访问的才是子类。

  java 编译器编译原理导致的。

  编译看左边,运行不一定看右边。

  编译看左边的意思:java 编译器在编译的时候会检测引用类型中含有指定的成员,如果没有就会报错。子类的成员是特有的,父类的没有的,所以他是找不到的。

  复制代码

  1 package study;

  2

  3 abstract class Animal{

  4 String name;

  5 static String color = "动物色";

  6

  7 public abstract void run();

  8

  9 public void eat(){

  10 System.out.println("这个是父类中的方法");

  11 }

  12 }

  13

  14 class Dog extends Animal{

  15 static String color = "黄色";

  16 //重写父类中的方法

  17 public void run(){

  18 System.out.println(name+"用四条腿在跑步");

  19 }

  20 //重写父类中的eat方法

  21 public void eat(){

  22 System.out.println("这个是子类中的方法");

  23 }

  24 }

  25

  26 class Fish extends Animal{

  27

  28 //重写父类的方法

  29 public void run(){

  30 System.out.println(name+"在自由自在地游泳");

  31 }

  32 }

  33

  34 public class star {

  35 public static void main(String[] args) {

  36

  37 Animal a = new Dog();//Animal 指针指向 Dog

  38 a.name = "小黄";

  39 a.run();

  40

  41 a.eat();

  42 System.out.println(a.color);

  43

  44 // a = new Fish();//Animal 指针指向 Fish

  45 // a.name = "小黄";

  46 // a.run();

  47 }

  48 }

  复制代码

  多态使用的场景:

  1.多态可以用于做形式参数,可以让方法接收更多的类型。

  2.多态用于返回类型,可以返回更多的数据类型。

  问题:想用子类的类型接收回来,这个时候就需要用到强制转换。

  如:Animal a = new Dog(); //多态

  Dog d = (Dog)a;

  多态的另一种实现:

  实现关系下的多态:

  接口 变量名 = new 实现类();

  接口是不能创建对象的,所以就使用实现这个接口的类来创建对象

  我返回的是圆的对象,不能用圆的引用变量来接收:返回的图形 -> 圆的父类

  基本数据类型的转换:大的数据 -> 小的接收(强制转换)

  复制代码

  1 package study;

  2

  3 //需求1:定义一个方法可以接收任意类型 的图形对象,求面积和周长。

  4 //需求2:定于一个方法可以返回任意类型的图形。

  5 abstract class MyShape{

  6 //定义两个方法求面积和周长。

  7 public abstract void getArea();

  8 public abstract void getLength();

  9 }

  10

  11 class Circle extends MyShape{

  12 int r;

  13 final double PI = 3.14;

  14

  15 //重写父类中的方法

  16 public void getArea(){

  17 System.out.println("圆的面积");

  18 }

  19 public void getLength(){

  20 System.out.println("圆的周长");

  21 }

  22 }

  23

  24 class Rect extends MyShape{

  25

  26 public void getArea(){

  27 System.out.println("矩形的面积");

  28 }

  29 public void getLength(){

  30 System.out.println("矩形的周长");

  31 }

  32 }

  33

  34 public class star {

  35 public static void main(String[] args) {

  36

  37 //需求1:定义一个方法可以接收任意类型 的图形对象,求面积和周长。

  38 getAreaAndLength(new Circle());

  39 getAreaAndLength(new Rect());

  40

  41 //需求2:定于一个方法可以返回任意类型的图

  42 MyShape a = getMyShape(0);//圆

  43 /*getAreaAndLength(a);//在这里拿到的是哪个型就计算哪个的面积和周长。*/

  44

  45 Circle c = (Circle)a;//引用数据类型的强制转换

  46 getAreaAndLength(c);//在这里拿到的是哪个型就计算哪个的面积和周长。

  47 }

  48

  49 public static void getAreaAndLength(MyShape ms){//这个参数拿到的是父类的对象,凡是属于这个父类的都可以使用这个方法。如果是圆就只能接收圆的

  50 ms.getArea();

  51 ms.getLength();

  52 }

  53

  54 public static MyShape getMyShape(int i){

  55 if (i == 0) {

  56 return new Circle();//圆

  57 }else if (i == 1) {

  58 return new Rect();//矩形

  59 }

  60 return null;

  61 }

  62 }