简单理解:一种类型多种形态
如上图:animal a = new Person()中编译时类型与运行时类型不一致,此时,我们就说产生了多态。
注意,编译时类型必须是运行时类型的父类或者祖先类
因为字段、静态方法不能被覆写,所以当子类和父类出现相同的字段或者静态方法时,在多态情况下,我们就看是谁的对象在调用,则就使用谁的值。怎么看是谁的对象?看这个对象保存在什么类型的变量中那就为谁的对象
实例代码:
class Test2{
public static void main(String[] args){
Person p = new Person();
//方式一
p.feedTuGou(new TuGou());
p.feedZangAo(new ZangAo());
p.feedSaMoYe(new SaMoYe());
//方式二
p.feedDog(new SaMoYe());
}
}
class Person{
//方式一
void feedTuGou(TuGou z){
z.eat();
}
void feedZangAo(ZangAo z){
z.eat();
}
void feedSaMoYe(SaMoYe z){
z.eat();
}
//方式二 运用多态 多态的好处:屏蔽各子类之间的实现差异,少写代码
void feedDog(Dog dog){ //Dog dog = new SaMoYe();
dog.eat();
//引用数据类型小转大,自动隐式转;大转小,强制转
}
}
class Dog{
void eat(){
System.out.println("吃狗粮。。。");
}
}
class TuGou extends Dog{
@Override
void eat(){
System.out.println("吃五谷杂粮。。。");
}
}
class ZangAo extends Dog{
@Override
void eat(){
System.out.println("吃肉食。。。");
}
}
class SaMoYe extends Dog{
@Override
void eat(){
System.out.println("吃进口狗粮。。。");
}
}
小转大自动隐式转;大转小,必须强制转。
Animal a = new Person(); 这是自动隐式转
Person p = (Person)a; 这是强制转
基本数据类型、引用数据类型小转大,自动隐式转;大转小,必须强制转。
能被final修饰得有:类、字段、方法、代码块、局部变量(唯一能修饰的)
不能被final修饰的有:构造方法
被final修饰的类:属于太监类,不能被继承;
被final修饰的字段:必须要有初始值,如果没有初始值,必须要有构造方法为其传值,一旦传值,不可改变;
被final修饰的方法:能被继承,不能被覆写;
被final修饰的局部变量:可以没有初始值,一旦传值,不可改变。
final一般修饰到字段上,被final所修饰的字段值是不能更改的
注意:被public static final所修饰的变量,叫做全局常量
示例代码:
class SingleInstance7{
public static void main(String[] args){
Person a = Person.getInstance();
Person b = Person.getInstance();
System.out.println(a==b);
}
}
/**
饿汉模式:一上来就要获得对象;饿汉模式的思路:产生实例的原因是外面不断的new,调用内部的构造方法,因此,我们将构造方法私有化,这个时候就只有在内部调用构造方法了,因此在内部new一个对象保存在instance里面,同时又要避免外面通过调用字段更改对象的值,所有将字段私有化,此时就需要放出一个公共的getter方法,让外面来获得这个对象的变量名,也就只能操作这个变量名。
饿汉模式存在的问题:占用内存。
static修饰的字段、代码块在使用该类的时候就会马上执行,如果我执行的是一个普通的方法,并不是获得
对象的方法,他也会立即创建对象。
*/
class Person{
private Person(){
}
private static Person instance = new Person();
public static Person getInstance(){
return instance;
}
}
示例代码:
class SingleInstaace8{
public static void main(String[] args){
System.out.println("come on 梓沐!");
}
}
/**
懒汉模式:在需要的时候才来创建一个实例;
懒汉模式存在的问题:线程安全问题,解决办法:加锁
*/
class Person{
private Person(){
}
private static Person instance;
public static Person getInstance(){
if(instace == null){
instance = new Person();
}
return instance
}
}
static修饰的字段或者代码块,在使用该类的时候马上执行,并且只会执行1次
示例代码:
class TestStatic12{
/**执行顺序: 静态代码块和静态成员 首先先执行,如果父类有,先执行父类的静态代码块和静态成员,再执行子类的静态代码块和静态代码块,再执行父类构造代码块,父类的构造方法,子类的构造代码块,子类的构造方法
执行顺序:类的静态代码块/类的静态变量----》子类的静态代码块/子类的静态变量----》父类的构造代码块/父类的构造方法--->子类的构造代码块/子类的 构造方法
在类中,static所修饰的字段和static修饰的代码块,谁在前面,谁就先执行
*/
public static void main(String[] args){
new B();//其实你在new子类的时候,它会先创建父类对象,然后在父类对象的基础上添加子类成员,最终成为子类对象
}
}
class A{
static int a = 3;
static{
System.out.println("A静态代码块"+a);
}
{
System.out.println("A构造代码块");
}
A(){
System.out.println("A无参数的构造方法");
}
}
class B extends A{
static{
System.out.println("B静态代码块");
}
{
System.out.println("B构造代码块");
}
B(){
System.out.println("B无参数的构造方法");
}
}
static修饰的字段和static修饰的代码块生命周期:
1.类被加载的时候,就存在jvm
2.类被卸载的时候,该生命周期就会结束(程序结束,关闭jvm)
class TestGroup6{
public static void main(String[] args){
Card card = new Card("110");
CellPhone c = new CellPhone("小米8",card);
c.show();
}
}
//组合关系的关键步骤理解:其实简单理解就是通过将要组合到另一个类里面的类型以字段的形式出现在这个类里面
class CellPhone{
private String brand;
private Card card; //这是一个字段,以后就是通过这种形式来组合另外一个类
CellPhone(){
}
CellPhone(String brand,Card card){
this.brand = brand;
this.card = card;
}
public void setBrand(String brand){
this.brand = brand;
}
public String getBrand(){
return brand;
}
public void setCard(Card card){
this.card = card;
}
public Card getCard(){
return card;
}
public void show(){
System.out.println("您的手机品牌为"+brand + " 您的手机号码为" + card.getNum()); //得到卡的号码
}
}
class Card{
private String num; //手机号码
Card(){
}
Card(String num){
this.num = num;
}
public void setNum(String num){
this.num = num;
}
public String getNum(){
return num;
}
}
转载于:https://www.cnblogs.com/limengkun/p/10617289.html