龙炎电商开启财富自由人生,宫益舒,小三影院
利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体。 数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节, 只保留一些对外接口使之与外部发生联系。用户无需知道对象内部的细节, 但可以通过对象对外提供的接口来访问该对象。
注意:局部变量名可以和成员变量名一样,在方法中使用的时候,采用就近原则。
以student类为例:
public class student { private string name; private int age; public student() { } public string getname() { return name; } public void setname(string name) { this.name = name; } public int getage() { return age; } public void setage(int age) { this.age = age; } } student s=new student();
具体步骤:
封装:一个标准的手机类的代码及测试
手机类
public class smartphone { private string brand; private double price; private string color; public string getbrand() { return brand; } public void setbrand(string brand) { this.brand = brand; } public double getprice() { return price; } public void setprice(double price) { this.price = price; } public string getcolor() { return color; } public void setcolor(string color) { this.color = color; } public void call(string name){ system.out.println("打电话给"+name); } public void sendmessage(string name){ system.out.println("给"+name+"发短信"); } public void playgame(){ system.out.println("玩游戏"); } }
手机测试类1
public class smartphonedemo { public static void main(string[] args) { smartphone sp=new smartphone(); sp.setbrand("iphone"); sp.setprice(6666); sp.setcolor("白色"); system.out.println("使用"+sp.getbrand()+"牌、售价为"+sp.getprice()+"元的" +sp.getcolor()+"的手机"); sp.call("jobs"); sp.sendmessage("kuke"); sp.playgame(); } }
一个手机对象的内存简图:
手机测试类2
public class smartphonedemo2 { public static void main(string[] args) { smartphone sp=new smartphone(); sp.setbrand("iphone"); sp.setprice(6666); sp.setcolor("白色"); system.out.println("使用"+sp.getbrand()+"牌、售价为"+sp.getprice()+"元的" +sp.getcolor()+"的手机"); sp.call("jobs"); sp.sendmessage("kuke"); sp.playgame(); smartphone sp2=new smartphone(); sp2.setbrand("小米"); sp2.setprice(1000); sp2.setcolor("黑色"); smartphone sp3=sp; sp.setprice(3555); system.out.println("使用"+sp.getbrand()+"牌、售价为"+sp.getprice()+"元的" +sp.getcolor()+"的手机"); } }
多个手机对象的内存简图:
执行顺序:
静态代码块---构造代码块---构造方法
public class codeblock { //构造方法 codeblock(){ int a=10; system.out.println(a); } //构造代码块 { int a=100; system.out.println(a); } //静态代码块 static { int a=1000; system.out.println(a); } public static void main(string[] args) { codeblock codeblock=new codeblock(); } }
输出结果:
1000 100 10
继承实现了 is-a 关系,例如 cat 和 animal 就是一种 is-a 关系,因此 cat 可以继承自 animal,从而获得 animal 非 private 的属性和方法。
继承应该遵循里氏替换原则,子类对象必须能够替换掉所有父类对象。
cat 可以当做 animal 来使用,也就是说可以使用 animal 引用 cat 对象。父类引用指向子类对象称为 向上转型 。
animal animal = new cat();
在子类方法中的查找顺序:
在子类方法的局部范围找,有就使用
在子类的成员范围找,有就使用
在父类的成员范围找,有就使用
如果还找不到,就报错
原因:因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前, 一定要完成父类数据的初始化。
方式一:子类通过super去显示调用父类其他的带参的构造方法
方式二:子类通过this去调用本类的其他构造方法 (子类一定要有一个去访问父类的构造方法,否则父类数据就没有初始化)
/** * 1. 子类中所有的构造方法默认会都会访问父类中空参数的构造方法 * 2. 每一个子类的构造方法第一条语句默认是:super() */ class father{ public father() { system.out.println("father的无参构造函数"); } } class son extends father{ public son() { //super(); system.out.println("son的无参构造函数"); } public son(string name) { //super(); system.out.println("son的带参构造函数"); } } public class inheritancedemo { public static void main(string[] args) { //使用无参构造函数初始化 son son=new son(); system.out.println("==========="); //使用带参构造函数初始化 son son2=new son("林青霞"); } }
输出结果:
father的无参构造函数 son的无参构造函数 =========== father的无参构造函数 son的带参构造函数 /** * 3. 如果父类中没有无参构造方法,该怎么办呢? 方式一:子类通过super去显示调用父类其他的带参的构造方法 方式二:子类通过this去调用本类的其他构造方法 (子类一定要有一个去访问父类的构造方法,否则父类数据就没有初始化) */ class parent{ public parent(string name){ system.out.println("parent的带参构造函数"); } } class child extends parent{ public child() { //子类通过super去显示调用父类其他的带参的构造方法 super("林青霞"); system.out.println("child的无参构造函数"); } public child(string name) { //方式一:子类通过super去显示调用父类其他的带参的构造方法 //super(name); //方式二:子类通过this去调用本类的其他构造方法 this();//嗲用child()的无参构造函数 system.out.println("child的带参构造函数"); } } public class inheritancedemo2 { public static void main(string[] args) { child c = new child(); system.out.println("=============="); child c2 = new child("林青霞"); } }
输出结果:
parent的带参构造函数
child的无参构造函数
==============
parent的带参构造函数
child的无参构造函数
child的带参构造函数
一个类的成员变量的初始化:
子类的初始化(分层初始化)
class x{ y b=new y(); //显式初始化 x(){ system.out.println("x"); } } class y{ y(){ system.out.println("y"); } } public class z extends x{ y y=new y(); public z() { super();//子类的初始化(分层初始化):先进行父类的初始化,然后再进行子类的初始化。 system.out.println("z"); } public static void main(string[] args) { new z(); } }
输出结果:
y x y z
重写(override):子类和父类中出现了一模一样的方法声明
注意:
final关键字是最终的意思,可以修饰类,修饰变量,修饰成员方法
注意:
在方法内部,该变量不可以被改变
在方法声明上,分为基本类型和引用类型的情况
(1)基本类型:是值不能变
(2)引用类型:是地址不能变,但是该对象的堆内存中的值是可以改变的
在对象构造完毕前即可(非静态常量),被final修饰的变量只能赋值一次。
继承:一个标准的动物类、猫类、狗类的代码及测试
动物类
class animal{ private string name; private int age; private string color; public string getname() { return name; } public void setname(string name) { this.name = name; } public int getage() { return age; } public void setage(int age) { this.age = age; } public string getcolor() { return color; } public void setcolor(string color) { this.color = color; } public void eat(){ system.out.print("吃什么东西?"); } }
猫类
class cat extends animal{ @override public void eat() { super.eat(); system.out.println("猫粮"); } public void play(){ system.out.println("小猫在玩耍"); } }
狗类
class dog extends animal{ @override public void eat() { super.eat(); system.out.println("狗粮"); } public void bark(){ system.out.println("小狗汪汪叫"); } }
测试
public class animaldemo { public static void main(string[] args) { dog dog=new dog(); dog.setname("旺财"); dog.setage(12); dog.setcolor("黄色"); system.out.println(dog.getname()+"\t"+dog.getage()+"\t"+dog.getcolor()); dog.eat(); dog.bark(); cat cat=new cat(); cat.setname("汤姆"); cat.setage(12); cat.setcolor("蓝色"); system.out.println(cat.getname()+"\t"+cat.getage()+"\t"+cat.getcolor()); cat.eat(); cat.play(); } }
某一个事物,在不同时刻表现出来的不同状态。 具体来讲,就是调用同一方法,会执行不同的功能。
实际生活:水在不同时刻的状态。
多态分为编译时多态和运行时多态:
好处
提高了代码的维护性(由继承保证)
提高了程序的扩展性(由多态保证)
弊端
不能访问子类特有功能(特有方法)
如何访问子类中的特有功能?
/** * 对象间的转型问题: 向上转型: parent f = new child(); 向下转型: child z = (child)f; //要求该f必须是能够转换为zi的。(父到子) */ class parent { public void show() { system.out.println("show fu"); } } class child extends parent { public void show() { system.out.println("show zi"); } public void method() { system.out.println("method zi"); } } public class polymorphismdemo { public static void main(string[] args) { parent fu=new child(); fu.show(); //fu.method();//不能访问子类特有功能(特有方法) child zi=(child)fu; //向下转型 zi.show(); zi.method(); } }
输出结果:
show zi show zi method zi class animal { public void eat(){} } class dog extends animal { public void eat() {} public void lookdoor() { } } class cat extends animal { public void eat() { } public void playgame() { } } public class polymorphismdemo3 { public static void main(string[] args) { //内存中的是狗 animal a = new dog(); dog d = (dog)a; //内存中是猫 a = new cat(); cat c = (cat)a; //内存中是猫 dog dd = (dog)a; //classcastexception } }
多态中对象内存图
/** * 多态中的成员访问特点: a:成员变量 编译看左边,运行看左边。 b:构造方法 创建子类对象的时候,访问父类的构造方法,对父类的数据进行初始化。 c:成员方法 编译看左边,运行看右边。( 由于成员方法存在方法重写,所以它运行看右边。) d:静态方法 编译看左边,运行看左边。(静态和类相关,算不上重写,所以,访问还是左边的) */ class fu{ public int num=100; public void show(){ system.out.println("show function"); } public static void function(){ system.out.println("function fu"); } } class zi extends fu { public int num = 1000; public int num2 = 200; @override public void show() { system.out.println("show zi"); } public void method() { system.out.println("method zi"); } public static void function() { system.out.println("function zi"); } } public class polymorphismdemo2 { public static void main(string[] args) { fu f = new zi(); system.out.println(f.num); //system.out.println(f.num2); f.show(); //找不到符号 //f.method(); f.function(); } }
输出结果:
100 show zi function fu
免费java高级资料需要自己领取,涵盖了java、redis、mongodb、mysql、zookeeper、spring cloud、dubbo高并发分布式等教程,一共30g。
传送门:https://mp.weixin.qq.com/s/jzddfh-7ynudmkjt0irl8q
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
浅析我对 String、StringBuilder、StringBuffer 的理解
使用IDEA搭建SSM框架的详细教程(spring + springMVC +MyBatis)
Springboot整合freemarker 404问题解决方案
引入mybatis-plus报 Invalid bound statement错误问题的解决方法
网友评论