标签:super关键字 spl lse 扩展 static [] hid 描述 语法
目的:隐藏实现细节,让使用者方便,让代码更安全
将对象的属性和行为封装起来,其载体就是类。类通常对客户隐藏其实现细节,这就是封装的思想。
封装(Encapsulation):把该隐藏的隐藏起来,该暴露的暴露出来。
封装需要通过访问控制修饰符(权限修饰符)来实现。
/* 权限修饰符: 本类 其他类(本包的其他类、其他包的子类、其他包的非子类) private √ × × × (只适用于本类中) 缺省(省略) √ √ × × (使用与本包中) protected(受保护的)√ √ √ × (本类 + 本包其他类 + 其他包的子类 ) public √ √ √ √ 权限修饰符的作用:限定某个类型、成员的可访问的范围、可见性的范围 权限修饰符可以修饰什么? private:成员(属性、方法、构造器、内部类) 缺省:外部类等类型、成员(属性、方法、构造器、内部类) protected:成员(属性、方法、构造器、内部类) public:外部类等类型、成员(属性、方法、构造器、内部类) 当public修饰外部类时,要注意类名必须与源文件名一致,即一个源文件只能有一个外部的public类 修饰符的学习:(1)可以修饰什么(2)修饰后有什么影响 */ //外部类 public class TestModifier{ //内部类 public class Inner{ } }
* 继承:延续,保留,并且扩展 extends
* 目的:代码的复用和功能扩展; 继承还可以表示is-a的逻辑关系;Student is a Person. Apple is a Fruit.
* 2、如何继承?
* 【修饰符】 class 子类名 extends 父类名{
* }
*
* 子类:SubClass,也称为派生类; 父类:SuperClass,也称为超类、基类
* 3、继承的特点
* (1)子类继承父类时,会继承父类的所有的属性、方法。* 但是因为修饰符的原因,某些属性和方法在子类中不可见。
* (2)子类“不会”继承父类的构造器;
* (3)在子类的构造器中一定会“调用”父类的构造器,并且默认调用的是父类的“无参”构造器。
如果父类没有“无参”构造,那么子类必须手动调用父类的“有参”构造。(子类在创建对象时候默认调用父类的无参构造器)
* (4)如果一个类没有显式的声明它的父类,那么它有一个默认的父类:java.lang.Object
* (5)在Java中,类的继承有“单继承限制”;意思:每一个子类只能有一个直接的父类,类似于每个人只有一个亲生父亲
* (6)Java中支持多层继承,即父类仍然可以有父类,子类会继承所有父类的属性和方法。 意思:代代相传
* (7)一个父类却同时可以有很多的子类,而且子类还可以有很多子类;* 意思:子孙满堂
* (8)子类可以扩展父类没有的属性和方法
* this关键字:当前对象 * (1)this.属性 * 当成员变量与局部变量重名时,在成员变量前面加"this." * * (2)this.方法 * 表示调用当前对象的成员方法,可以省略this. * * (3)this()或this(实参列表) * this()或this(实参列表)调用本类的无参构造 * * super关键字:父类的 * 前提:要通过super调用父类的属性、方法、构造器,必须要求他们的可见性是在子类中可见的。 * * (1)super.属性 * 当子类的属性与父类的属性重名时,可以使用super.属性 表示父类的属性。 * * (2)super.方法 * 当子类重写了父类的方法,又想调用父类被重写的方法,那么可以使用“super.父类的方法名 被重写方法” * * (3)super()或super(实参列表) * super()表示调用父类的无参构造器,可以省略, * super(实参列表)表示调用父类的有参构造,不可以省略,特别是父类没有无参构造时 * 要求:和this()、this(实参列表)一样,必须在构造器的首行。
public Manager() { super(); } public Manager(String name, double salary, double bonus) { super(name, salary); //调用父类的有参构造 加上 子类自己扩展的属性。 this.bonus = bonus; } if(amount < balance){ //正常取 super.withdraw(amount); //调用父类的withdraw方法;方法的重写。
多种形态,目的是使代码更灵活,功能更丰富。
* 如何理解它? 针对方法 * 1、方法的重载与重写:一个功能有多种形式 * public static int getMax(int x, int y) * public static int getMax(int x, int y,int z) * public static double getMax(double x, double z) * 功能都是找最大值,它有多种形式 * * public class Employee{ * public String getInfo(){ * .... * } * } * public class Manager extends Employee{ * public String getInfo(){ * .... + 奖金 * } * } * 父子类中该方法都是返回对象的详细信息,但是父子类中有两种形式 * * 2、对象的多态性 * 某个对象在Java中可能出现 1)编译时类型; 2)运行时类型,不一致 * 编辑代码并且javac java * 前提条件: * (1)类有继承关系 * (2)方法的重写 * (3)多态引用:父类的变量指向子类的对象 * Person p = new Man(); * 出现的对象多态性的现象: * 编译时按照父类的类型编译,运行时按照子类的类型运行,执行的方法是子类重写的方法体。 * */
public class TestPolymorphism { public static void main(String[] args) { // Object obj = new String("hello"); // 此时的obj对象就有两种类型,编译时类型是Object类型,运行时是String类型 } }
//本态引用:编译时类型和运行时类型是一样的 // Person p = new Person(); // Man m = new Man(); // Girl g = new Girl();
Person p = new Man(); //编译时类型是Person,运行时类型是Man p.eat(); //运行时候是Man类型; p.smoke();//编译时报错,因为p在编译时按照Person类型,Person类型中没有smoke()方法 class Person{ public void eat(){ System.out.println("吃吃吃饭"); } public void sleep(){ System.out.println("睡觉觉"); } } class Man extends Person{//难人 public void eat(){ System.out.println("狼吞虎咽"); } public void sleep(){ System.out.println("呼呼大睡"); } public void smoke(){ System.out.println("吞云吐雾"); } }
* 多态的第一个应用:多态数组 * 元素的类型是父类的类型,元素存的是子类的对象 * * 需求:用一个数组来存储多个图形对象,这里面可能有圆对象,可能有矩形对象,统一管理他们,要显示他们的面积、周长、向下信息等,甚至按照面积排序... * 1、声明一个Circle类,有半径radius,有求面积的方法,求周长的方法,返回详细信息的方法 * 2、声明一个Rectangle矩形类,有长和宽,有求面积的方法,求周长的方法,返回详细信息的方法 * 3、声明一个父类Graphic图形类,让Circle和Rectangle继承它 * * 类:一类具有相同特性的事物的抽象描述。
public class TestUse1 { public static void main(String[] args) { //多态引用,左边的arr[]是父类的类型Graphic,右边赋值的是子类的对象; Graphic[] arr = new Graphic[3]; //数组的声明和初始化 arr[0] = new Circle(2); arr[1] = new Ractangle(3,2); arr[2] = new Circle(6.1); //编译时g按照Graphic的父类类型编译,执行的时候,执行的是子类重写的方法体 for(Graphic num: arr){ System.out.println(num.getInfo() + "\n"); //System.out.println(num.getArea() + "\t"); } } }
public class TestUse1 { public static void main(String[] args) { //多态引用,左边的arr[]是父类的类型Graphic,右边赋值的是子类的对象; Graphic[] arr = new Graphic[3]; //数组的声明和初始化 arr[0] = new Circle(2); arr[1] = new Ractangle(3,2); arr[2] = new Circle(6.1); //编译时g按照Graphic的父类类型编译,执行的时候,执行的是子类重写的方法体 for(Graphic num: arr){ System.out.println(num.getInfo() + "\n"); //System.out.println(num.getArea() + "\t"); } } } package com.atguigu.variable; public class Graphic { public double getArea(){ return 0.0; } public double getPrimeter(){ return 0.0; } public String getInfo(){ return ""; } } package com.atguigu.variable; public class Circle extends Graphic{ private double radius; public Circle() { super(); } public Circle(double radius) { super(); this.radius = radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public double getArea(){ return Math.PI * radius * radius; } public double getPrimeter(){ return 2 * Math.PI * radius; } public String getInfo(){ return "半径" + radius + "\t面积" + getArea() + "\t周长" + getPrimeter(); } } package com.atguigu.variable; public class Ractangle extends Graphic{ private double length; private double width; public Ractangle() { super(); } public Ractangle(double length, double width) { super(); this.length = length; this.width = width; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getArea(){ return length * width; } public double getPrimeter(){ return 2 * (length + width); } public String getInfo(){ return "长" + length +"\t宽:"+ width + "\t面积" + getArea() + "\t周长" + getPrimeter(); } }
* 多态的应用之二:多态参数 * 形参是:父类类型 * 实参是:子类的对象 * * 需求: * 1、声明一个Circle类,有半径radius,有求面积的方法 * 2、声明一个Rectangle矩形类,有长和宽,有求面积的方法 * 3、声明一个Triangle三角形,有三边,有求面积的方法 * 3、在测试类中,声明一个方法,功能:可以比较任意两个图形对象的面积,是否相等
public class TestUse2 { public static void main(String[] args) { Circle c = new Circle(2); Ractangle r = new Ractangle(3, 2); //实参给形参赋值 //形参的类型:Graphic,实参的类型:一个是Circle,一个是Rectangle //隐含了:Graphic g1 = c;//多态引用 //隐含了:Graphic g2 = r;//多态引用 boolean result = equalsGraphic(c, r); if(result){ System.out.println("面积相等"); }else{ System.out.println("面积不相等"); } } //可以比较任意两个图形对象的面积,是否相等 //返回值类型:boolean //形参?两个图形类型 public static boolean equalsGraphic(Graphic g1, Graphic g2){ //g1和g2编译时按照Graphic类型,运行时g1按照Circle,g2按照Rectangle类型 if(g1.getArea() == g2.getArea()){ return true; }else{ return false; } } }
* 基本数据类型:byte,short,int,long,float,double,boolean,char * 1、自动类型转换 * byte,short,char->int->long->float->double * boolean不参与 * .... * * 2、强制类型转换 * double->float->long->int->char,byte,short * 强制类型转换需要(),可能损失精度或溢出 * boolean不参与 * .... * * 父子类之间类型转换: * 1、向上转型:自动完成 * Person p = new Man();//一个Man的对象在编译期间向上转型为Person类型 * * Graphic[] arr = new Graphic[5]; * arr[0] = new Circle(2);//一个Circle对象在编译期间向上转型为Graphic类型 * * 2、向下转型:强制完成 * Person[] arr = new Person[5]; arr[0] = new Man();//向上转型 Man m = (Man) arr[0];//向下转型 * * 向下转型之前,一定发生过向上转型。 * * * 父类的变量中可以存储子类的对象, * 但是子类的变量中是不能存储父类的对象。
* 关键字:instanceof * 为了避免转型的失败,可以在转型之前加instancof判断
public class TestClassCast { public static void main(String[] args) { Person[] arr = new Person[3]; arr[0] = new Man(); arr[1] = new Girl(); arr[2] = new Person(); //希望调用Man类型的smoke()方法 //arr[0].smoke(); //编译时,arr[0]是按照父类Person类型编译的 Man m = (Man) arr[0]; //向下转型; m.smoke(); //编译没保错,因为编译时,arr[1]按照父类Person类型编译的,从Person类型向下转为Man,语法上可以 //Man m2 = (Man)arr[1];//运行时,发生java.lang.ClassCastException:类型转换异常 //m2.smoke(); //.Girl cannot be cast to .Man Man m3 = (Man)arr[2];//运行时,发生java.lang.ClassCastException:类型转换异常 m3.smoke(); //.Person cannot be cast to .Man } }
Man m -->>指向Man对象是可以的
Man m2 --->>不能指向Girl对象,因为它俩之间没有继承关系的。
Man m3 ---->>不能指向Person父对象。
public class TestClassCast { public static void main(String[] args) { Person[] arr = new Person[3]; arr[0] = new Man(); arr[1] = new Girl(); arr[2] = new Person(); for(Person p : arr){ p.eat(); //p.sleep(); if(p instanceof Man){ Man m =(Man) p; m.smoke(); }if(p instanceof Girl){ Girl g = (Girl) p; g.shopping(); } } } }
标签:super关键字 spl lse 扩展 static [] hid 描述 语法
原文地址:https://www.cnblogs.com/shengyang17/p/10010418.html