网站建设 月嫂 模板,阿里邮箱企业登录入口,临淄关键词网站优化哪家好,科技手抄报内容目录前言继承的概念和实现extends关键字super关键字继承过来的属性和方法的权限研究方法重写OverrideObject根类常见方法toString()常把toString()方法重写后应用equals()重写#xff1a;判断两个对象p1和p2特征是否相同IDEA的重写模板#xff1a;敲equals可选择的方案之一St…
目录前言继承的概念和实现extends关键字super关键字继承过来的属性和方法的权限研究方法重写OverrideObject根类常见方法toString()常把toString()方法重写后应用equals()重写判断两个对象p1和p2特征是否相同IDEA的重写模板敲equals可选择的方案之一String 类重写判断字符串是否相等继承练习java面向对象下的简单工厂模式前言
下面C语言的代码中定义了两个在内容上高度重复的结构体
#include stdio.hstruct Person //人
{int name;char* address;void (*pEat)(); void (*pDrink)();
};struct Student //学生也是人所以有一定的重复性
{ int name;char* address;void (*pEat)();void (*pDrink)();int score; //学生独有的特征有分数要上学void (*goToSchool)();
};然而对于C语言来说这两个结构体没有任何联系这样造成了代码的浪费重复。
而java的继承特性就解决了这一问题。
继承的概念和实现
生活中继承的概念随处可见。
比如 java继承背后的思想是基于已存在的类来构建新类。
当从已存在类继承时就重用了他的方法和属性还可以添加新的方法和属性来定制新类以应对要求。
继承的意义:代码重用,体现不同抽象层次
约定从其他类导出的类叫做子类通常父类更通用更抽象子类更特殊更具体。
在java中除了object外所有类都是子类都只有唯一的父类即为object类。 所以继承在OOPObject-Oriented Program面向对象编程 中不可或缺创建一个类时总是在继承 extends关键字
在java语言中用extends关键字来表示一个类继承了另一个类,如Student继承了Person
public class Student extends Person{
...
}
123
例子
class Person {String name;String address;void eat() {System.out.println(人吃饭);}void drink() {System.out.println(人喝水);}
}class Student extends Person{ //可以直接使用Person中的属性了int score;void goToSchool() {System.out.println(学生要上学);}
}public class Demo1 {public static void main(String[] args) {Person p new Person();p.name 人;p.eat();Student s new Student();s.name 学生; //person中的特征s.eat(); //person中的方法}
}super关键字
super和this关键字的特点类似super代表的是对父类对象的引用
作用
1当子父类的成员出现同名时可以通过super来区分 2子类的构造方法中通过super关键字调用父类的构造方法
强调 1当构造一个子类对象的时候一定会先调用父类的构造方法来构造父类的对象。 2调用父类构造方法的语句必须是子类构造方法中的第一条指令 super关键字的例子
class Person {String name;String address;void eat() {System.out.println(人吃饭);}void drink() {System.out.println(人喝水);}//Person(){}//解决方法一在父类中写一个无参的构造方法Person(String name,String address){//构造方法给属性赋初值this.name name;this.address address;System.out.println(父类构造方法被调用);}
}class Student extends Person{ //可以直接使用Person中的属性了int score;void goToSchool() {System.out.println(学生要上学);}/*Student(){ //如果不写父类中已有的构造方法的话系统分配类似于这样的无参构造方法//如果父类写了构造方法而子类没有“对应的”构造方法就会出错//解决方法一在父类中写一个无参的构造方法//解决方法二应用super关键字在子类中完成对父类构造方法的引用}*/ //父类可能有多个构造方法子类只需要引用一个初始化自己就好//解决方法二Student(String name,String address){ //没有下面的super的话 系统不认定这是一个构造方法super(name, address); //调用了父类的构造方法这个语句必须放在子类构造方法的第一句System.out.println(子类构造方法被调用);}public void eat(){ //因为父类已经有了方法eat这里权限不能降低所以加public,后面讲多态会介绍方法的重写super.eat(); //调用父类的eat,super是对父类的引用。//子类中有eat,父类也有同名的方法如何区分是父类还是子类的eat用super!System.out.println(student eat);}
}public class Demo1 {public static void main(String[] args) {//在实例化一个对象的时候子类的构造方法调用会导致父类的构造方法也被调用Student s new Student(小明,西祠胡同1号);s.eat();}
}结果
父类构造方法被调用
子类构造方法被调用
人吃饭
student eat父类的地址西祠胡同1号
继承过来的属性和方法的权限研究
重点看看父类中的私有属性private会不会被子类继承如果可以显然其他的默认属性如public、默认等肯定也可以。
class Person {String name;private String address; //私有的属性void eat() {System.out.println(人吃饭);}Person(String name,String address){this.name name;this.address address;System.out.println(父类构造方法被调用);}
}class Student extends Person{int score;void goToSchool() {System.out.println(学生要上学);}Student(String name,String address){super(name, address); //调用了父类的构造方法 可以间接的访问到父亲的address}/*void setAddress(String address){this.address address; //这里提示了address是父类私有的说明实际上没有被继承过来 //不给你用父亲”私藏的“所有东西儿子都是不知道的继承不到}*/
}结论父类私有的无论是方法还是属性都无法被子类继承。
方法重写Override
方法重写是指子类可以根据需要对从父类继承过来的方法进行改写是多态机制的前奏。
1重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值 2重写方法不能比被重写方法有更严格的访问权限 3父类中的私有方法不能被重写 4在子类重写的方法中继承调用父类被重写的方法可以通过super.函数名获取 注意区别前面封装部分提到的方法重载是同一方法名不同参数列表。而重写的话则全部都是一样的包括函数名、参数、返回值。 例子
class Person
{String name;private String address;public void printName(){System.out.println(namename);}private void printAddress(){ //父类的私有方法想要重写这个方法子类中的方法不能是privateSystem.out.println(addressaddress);}
}class Student extends Person
{int score;public void printName() { //1重写方法必须和被重写方法具有相同的名称、参数列表和返回值//2重写方法不能比被重写方法有更严格的访问权限System.out.println(子类name name); //方法的实现改了也是重写啊别看就改了一点}public void printAddress(){ //如果这里用的是private那下面的stu1.printAdd就会报错System.out.println(想用你的私有方法);//注意如果父类方法权限是private子类不能用private去重写这个方法} //这对于子类来说父类是不可见的是看不到父类的方法的
} //所以这对于子类来说就是【构造了一种新的方法】既不是方法重写也不是方法重载//是不是重写就概念的东西初学也不必争辩知道这么用就行
public class Demo1 {public static void main(String[] args){Student stu1 new Student();stu1.name 小明;stu1.printName();stu1.printAddress(); }
}运行结果
子类name小明
想用你的私有方法 //说明子类对父类私有方法的重写 “成功” Object根类常见方法
java中所有类都直接或间接继承自java.lang.Object类是所有类的根类。如hashcode()、clone()、getClass()、finalize()。
重点介绍下面两类toString()和equals()
toString()
做个简单的测试
package com.huatianzhu.learn;class Person
{String name;
}public class Demo1 {public static void main(String[] args) {Person p new Person();p.name huatianzhu;System.out.println(p.toString());}
}结果
com.huatianzhu.learn.Person49e4cb85
1
为什么会是上面的结果
返回格式
getClass().getName()Integer.toHexString(hashCode());
1 1getClass().getName()代表返回对象所属类的包名.类名即com.huatianzhu.learn 2Integer.toHexString(hashCode())代表将对象的哈希值用16进制表示其中hashCode()代表返回该对象的哈希值。 常把toString()方法重写后应用
然而在实际开发中通常希望toString()方法返回的不只是上面的信息所以Object的toString()方法通常会被重写如下
Override
public String toString() {return Person{ name name \ , address address \ };
}
1234567
这是IDEA的重写方案自动补全后就跳出来了如上代码
运行结果使得toString()根据实际需求打印出信息
Person{namehuatianzhu, addressnull}
1
equals()
equals方法没有重写的话用于判断对象的内存地址引用是否使用一个地址。重写之后一般用来比较对象的内容是否相等比如student对象里面有姓名和年龄我们重写判断这两个对象是相等的
重写判断两个对象p1和p2特征是否相同
package com.huatianzhu.learn;import java.util.Objects;class Person {String name;String address;public boolean equals(Person p){//传对象参数//Person p (Person)arg0;不给这样做强换if(this.address p.address this.name p.name)//C语言比较字符串使用strcmp()return true;elsereturn false;}
}public class Demo1 {public static void main(String[] args) {Person p1 new Person();p1.name xiaoming;p1.address 西祠胡同1号;Person p2 new Person();p2.name xiaoming;p2.address 西祠胡同1号;System.out.println(p1.equals(p2));}
}运行结果
true
1
IDEA的重写模板敲equals可选择的方案之一
package com.huatianzhu.learn;import java.util.Objects;class Person {String name;String address;//下面两个override都是IDEA自带的重写模板Overridepublic boolean equals(Object o) {if (this o) return true;if (!(o instanceof Person)) return false;Person person (Person) o;return Objects.equals(name, person.name) Objects.equals(address, person.address);}Overridepublic int hashCode() {return Objects.hash(name, address);}
}public class Demo1 {public static void main(String[] args) {Person p1 new Person();p1.name xiaoming;p1.address 西祠胡同1号;Person p2 new Person();p2.name xiaoming;p2.address 西祠胡同1号;System.out.println(p1.equals(p2));}
}运行结果
true
1
String 类重写判断字符串是否相等
String 类中重写了 equals() 方法用于比较两个字符串的内容是否相等。
语法public boolean equals(Object anObject)
实例:
public class Test {public static void main(String args[]) {String Str1 new String(huatianzhu);String Str2 Str1; //直接把 对象1 赋值给 对象2 String Str3 new String(chenlichen);boolean retVal;retVal Str1.equals( Str2 );System.out.println(返回值 retVal );retVal Str1.equals( Str3 );System.out.println(返回值 retVal );}
}运行结果
返回值 true
返回值 false
12
继承练习java面向对象下的简单工厂模式
之前做智能家居项目的时候用了C语言的链表做了简单工厂模式。在java中感受一下这面向对象主要是继承的魅力。免除了C语言中在工厂链表增加节点的模式其实底层的实现机制也是类似链表。
abstract class Device //抽象类abstract后面也会有介绍
{String open;String close;void init(){System.out.println(设备的初始化);}abstract void diffFunction(); //抽象方法不同设备有不同的使用方法不好在//这个大的类进行规划所以做得抽象点Device(String cmd1,String cmd2){this.open cmd1; //设备的开关指令this.close cmd2;}
}class Camera extends Device
{Camera(String cmd1,String cmd2){super(cmd1,cmd2); //当父类有构造方法时非空子类必须调用父类的} //构造方法进行属性的初始化void diffFunction(){System.out.println(相机拿来拍照); //对抽象方法的具体化相机是拿来拍照的} //也必须具体化否则这个继承的子类也要修饰成抽象类/*public void takePhoto(){System.out.println(拍了张张片); //每个设备不一样的功能可以在其父类Device中进行方法的抽象} */ //然后在子类中进行具体化这是面向对象很方便的地方
}class Lightone extends Device
{Lightone(String cmd1,String cmd2){super(cmd1,cmd2);}void diffFunction(){System.out.println(第一个灯拿来照亮卧室);}/*void printInfo(){System.out.println(灯1额外执行的东西);}*/
}class Lighttwo extends Device
{Lighttwo(String cmd1,String cmd2){super(cmd1,cmd2);}void diffFunction(){System.out.println(第二个灯拿来照亮浴室);}/*void printInfo(){System.out.println(灯2额外执行的东西);}*/
}class Factory
{ //返回值是对象Device的方法static Device getDevice(String name){ //作为静态方法不用依靠Factory创建的对象访问if(name 相机){return new Camera(open-c1,close-c1);//因为Device是抽象的不可实例化} //但其继承这个抽象类的类使用时必须实例化else if(name 灯1){ //所以此处方法返回类型写的是Device但返回了具体的实例对象//这也是以后会讲解到的多态。return new Lightone(open-d1,close-d1);}else if(name 灯2){return new Lighttwo(open-d2,close-d2);}elsereturn null;}
}public class Test {public static void main(String[] args) {Factory.getDevice(相机).diffFunction();//通过名字找到子类并调用子类的功能方法Factory.getDevice(灯1).diffFunction();//是不是像极了C语言的工厂模式从链表中找设备Factory.getDevice(灯2).diffFunction();}
}