多态
多态通俗点就是创建一个对象是父类的类型,但是是子类的对象。
父类名称 类名 =new 子类名称()
编译时把对象看成是父类,运行时把对象看作是子类。
多态的好处:可以减少代码的冗余性。
多态的特征:把子类看成父类对象,但是在运行的时候,表现出子类的特征。
注意:继承是多态的前提,但在开发中涉及的多态:接口与实现类的关系。
引用类型转换:
自动类型转换:把子类对象赋给父类变量(多态形式)
Animal a=new Dog()
强制类型转换:
Dog b=(Dog) a
多态相关代码:
//父类
class Pet {
public void eat() {
System.out.println("正在吃东西");
}
public void feed(){
System.out.println("正在喂宠物");
}
}
//子类
class Dog2 extends Pet{
public void eat(){
System.out.println("正在啃骨头");
}
public void feed(){
System.out.println("正在喂狗");
}
}
class Cat2 extends Pet{
public void eat(){
System.out.println("正在吃鱼");
}
public void feed(){
System.out.println("正在喂猫");
}
}
class Master{
/*public void feed(Cat2 cat2){
cat2.feed(); 对应 Master person=new Master();
person.feed(new Cat2()); */
public void feed(Pet pet)
{
pet.feed();
}
}
public class 多态 {
public static void main(String[] args) {
//此代码是先了解多态及多态的两种类型转换
//类型转换的作用是当构造完多态,想访问子类中的属性时,需进行强制类型转换
Pet cat1=new Cat2();//构成多态(自动类型转换)对象是Cat2的属性,类型是Pet的类型
cat1.eat();//由输出结果可知此时输出的是正在吃
//Cat2 cat1=(Cat2) cat;强制类型转换 将cat由Pet类型转换为Cat2类型 此行不报错,因为定义多态时对象是Cat2,与转换类型一直
// cat1.eat();
//Dog dog=(Dog) cat; 报错:Pet无法转换为Dog
// 若为 Pet dog=new Dog2; Dog dog1=(Dog) dog;这样就不会出问题
/*可以用instanceof加上if else语句对是否能进行强制转换进行判断*/
if (cat1 instanceof Cat2)
{
Cat2 cat2=(Cat2) cat1;//转换类型时要重新实例化一个对象cat2
System.out.println("执行了语句1");
}
else
{
Dog2 dog2=(Dog2) cat1;
System.out.println("执行了语句2");
}
System.out.println();//空行区分
/*Master person=new Master();
person.feed(new Cat2()); 这种方法是可以的,但是如果要利用这种方法会很麻烦,
要在Master类中写很多feed的方法*/
Master person=new Master();
person.feed(new Cat2());
person.feed(new Dog2());
//此种方法很巧妙的利用了多态的性质
}
//多态访问的是父类中单独的属性和方法,并且优先访问子类中重写的方法
}
final
final修饰符可以修饰类,方法,变量。
final所修饰的类不能有子类
final所修饰的方法不能被子类所覆盖,父类中提供好的算法业务操作时,之应该让子类调用不能让子类继承时使用final修饰的方法。
final修饰的变量:
对于基本数据类型,值不能再改变,只能赋值一次。
对于引用数据类型,变量的地址不能改变,但变量中的内容可以改变
相关代码:
class show{
String name="张三";
public show(){
}
public void show(String name){
this.name=name;
}
}
public class final关键字 {
public static void main(String[] args) {
final int num=17;//final修饰基本数据类型
//num=12;此句出现问题,final所定义的变量只能赋值一次
System.out.println(num);
System.out.println();
final show u =new show();
System.out.println(u.name);
u.show("李四");
// u=new 关键字.show("李四"); final定义的引用数据类型可以改变对象中的值,但不能改变对象所对应的的地址
System.out.println(u.name);
}
}
包装类 装箱 拆箱
这里说的是基本数据类型的包装类。
包装类里有很多该数据类型的相关东西,例如最大最小值,进制转换,等等,另外包装类所确定的类型是对象,对象可以表示null和0两种状态。
8大基本数据类型的包装类:Byte,Short,Integer,Long,Character,Float,Double,Boolean
8大基本数据类型的包装类都是final修饰的类。
装箱:把一个基本数据类型值,转换为对应包装类的对象(例如:int---->integer)
拆箱:把一个包装类的对象,转换为对应的基本数据类型的变量(integer---->int)
自动装箱:可以直接把一个基本数据类型的值,赋值给对应包装类对象。
自动拆箱:可以直接把一个包装类的对象的值,赋给对应基本数据类型的变量。
Integer num1=new Integer(17);//装箱
Integer num2=Integer.valueOf(17);//装箱的另外一种写法
int num3=num2.intValue();//拆箱
Integer num4=16;//自动装箱
int num5=num4;//自动拆箱
//num1,num2,num4都是对象,num3,num5是值
因为自动拆箱操作:switch语句,不只支持byte,short,char,int,现在也支持Byte,Short,Character,Integer。
包装类有一些基本操作:
1.都有MAX_VALUE/MIN_VALUE/SIZE(数据占位)
2.构造器:
第一种:参数是对应基本数据类型
Integer num=new =Integer(17)
第二种:参数是String类型
Integer num=new Integer(“17”);
方法:
String---->int类型
public static int parseInt(String str):把一个字符串的数据,转换为int类型
int---->String
String str =String.valueOf(17);//“17”
模板方法设计模式
概念:在父类的一个方法中定义一个总体算法的骨架(模板方法),而将某一些步骤延迟到子类中,因为不同的子类实现细节不同。模板方法是的子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
部分代码://计算1000个整数和1000个字符串相连接的耗时时间
abstract class OperateTemplate
{
public final long getTogetTime(){
long begin=System.ourrentTimeMillis();
doWork();
long end =System.ourrentTimeMillis();
return end-begin;
}
abstract protected void doWork();
}
class IntOperate extends OperateTemplate
{
public void doWork(){
long total=0;
for(int i = 1;i<=10000;i++)
{
total+=i;
}
}
class StringOperate extends OperateTemplate
{
public void doWork(){
String str ="";
for(int i=1;i<10000;i++)
{
str=str+i;
}
}
}
抽象方法和抽象类
抽象方法:使用abstract修饰且没有方法体的方法。
特点:
1.没有方法体,留给子类去实现。
2.抽象方法的修饰符不能是private和final和static
private和final不可以是因为抽象方法是要留给子类去实现的
static不行是因为static写的方法不能改变
3.抽象方法必须定义在抽象类或接口中
抽象类:使用abstract关键字修饰的类
特点:
1.不能创建实例即不能new一个抽象类
2.抽象类可以不包含抽象方法,但若有抽象方法,则该类一定为抽象类。
3.若子类没有实现父类所有的抽象方法,那么子类也得作为抽象类。
4.构造方法不能定义成私有的,因为继承时,会执行父类的构造方法。
5.抽象类不能用final来修饰,因为必须有子类,抽象方法才得以实现。
6.是不完整的类,需作为基类,功能才能实现。
抽象类与普通类的区别:
抽象类:也是一个类,可以定义抽象方法(没有方法体的方法)
抽象类不能创建对象。
除此之外都一样。
接口和实现类
定义:接口主要用来定义方法,规定必须具有某些行为(方法)
其他类若想拥有该功能,就必须实现接口。
[修饰符] interface 接口名{ }
接口成员:
1.全局静态常量 默认public static final修饰
2.公共静态内部类 默认public static 修饰
3.公共的抽象方法 默认public abstract修饰
public interface 接口的定义及成员 {//默认abstract
int age=17;//接口中定义的变量默认以public static final修饰,因此可以用接口来作为常量类
void walk();//接口中的方法默认以public abstract为前缀
class walk{} //接口中的类默认以public static修饰
}
接口的特点:
1.没有构造方法,不能实例化
2.接口只能继承接口,不能继承类,且支持多继承(用逗号分开),一个接口允许有多个父接口
3.接口成员的特点
interface IWalkable{
void walk();
}
interface ISwimable{
void swim();
}
interface 两栖动物 extends IWalkable,ISwimable{//接口可以继承多个接口
}
class Animals{
}
class 实现走类 extends Animals implements IWalkable{//实现类必须实现所实现接口的全部方法,否则必须加abstract来修饰类
public void walk(){//此时必须用public,因为接口中的方法默认为public abstract
System.out.println("走路");
}
}
class 实现游类 extends Animals implements ISwimable {//若要同时继承类同时实现接口,则必须先继承类再实现接口,格式如此
public void swim() {
System.out.println("游泳");
}
}
class 实现两栖类 extends Animals implements IWalkable,ISwimable{//或写成实现动物
// 实现类可以实现多个接口
public void walk(){
System.out.println("走啊走");
}
public void swim(){
System.out.println("游啊游");
}
}
class interfaceText {
public static void main(String[] args) {
实现游类 i=new 实现游类();
i.swim();
实现走类 j=new 实现走类();
j.walk();
实现两栖类 k=new 实现两栖类();
k.swim();
k.walk();
ISwimable p=new 实现游类();//多态
p.swim();
}
}