java学习中,面向对象的三大特性:封装、继承、多态 以及 super关键字和方法的重写(java 学习中的小记录)
作者:王可利(Star·星星)
封装
权限修饰符: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.多态用于返回类型,可以返回更多的数据类型。
问题:
我返回的是圆的对象,不能用圆的引用变量来接收:返回的图形 -> 圆的父类
基本数据类型的转换:大的数据 -> 小的接收(强制转换)
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 }