1、封裝性
一個對象和外界的聯系應當通過一個統一的接口,應當公開的公開,應當隱藏的隱藏。
屬性的封裝:Java中類的屬性的訪問權限的默認值是default,要想隱藏該屬性或方法,就可以加private(私有)修飾符,來限制只能夠在類的內部進行訪問。對於類中的私有屬性,要對其給出一對方法(getXxx(),setXxx())訪問私有屬性,保證對私有屬性的操作的安全性。
方法的封裝:對於方法的封裝,該公開的公開,該隱藏的隱藏。方法公開的是方法的聲明(定義),即(只須知道參數和返回值就可以調用該方法),隱藏方法的實現會使實現的改變對架構的影響最小化。
public class TestDemo {
public static void main(String[] args) {
Person person=new Person();
person.tell();
person.setAge(-20);
person.setName("張三");
person.tell();
}
}
class Person{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>0&&age<150){
this.age = age;
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
void tell(){
System.out.println("姓名:"+name+";年齡:"+age);
}
}
備注:
(1)Java匿名對象:只需要使用一次的場所。例如:new Person().tell();
(2)Java構造方法:構造方法名稱必須與類名一致,沒有返回指,可以重載,主要為類中的屬性初始化。
(3)值傳遞的數據類型:八種基本數據類型和String(String也是傳遞的地址,只是String對象和其他對象是不同的,String是final的,所以String對象值是不能被改變的,值改變就會產生新對象。那麼StringBuffer就可以了,但只是改變其內容,不能改變外部變量所指向的內存地址)。
引用傳遞的數據類型:除String以外的所有復合數據類型,包括數組、類和接口。
123456789101112131415161718192021222324252627282930 public class TestRef4 {
public static void main(String args[])
{
int val=10;;
StringBuffer str1, str2;
str1 = new StringBuffer("apples");
str2 = new StringBuffer("pears");
System.out.println("val:" + val);
System.out.println("str1 is " + str1);
System.out.println("str2 is " + str2);
System.out.println("...............................");
modify(val, str1, str2);
System.out.println("val is " + val);
System.out.println("str1 is " + str1);
System.out.println("str2 is " + str2);
}
public static void modify(int a, StringBuffer r1,StringBuffer r2)
{
a = 0;
r1 = null;
r2.append(" taste good");
System.out.println("a is " + a);
System.out.println("r1 is " + r1);
System.out.println("r2 is " + r2);
System.out.println("...............................");
}
}
輸出結果為:
val:10
str1 is apples
str2 is pears
...............................
a is 0
r1 is null
r2 is pears taste good
...............................
val is 10
str1 is apples
str2 is pears taste good
(4)this關鍵字:表示類中的屬性或方法;調用類中的構造方法,例如:this();表示當前對象。
(5)static關鍵字:static申明屬性為全局屬性;static申明方法直接通過類名調用;使用static方法時,只能訪問static申明的屬性和方法,而非static申明的屬性和方法時不能訪問。
2、繼承性
在程序中,使用extends關鍵字讓一個類繼承另一個類,繼承的類為子類,被繼承的類為父類,子類會自動繼承父類所有的方法和屬性
class 子類 extends 父類{}
示例1:
public class ExtendsDemo1 {
public static void main(String[] args) {
Student student=new Student();
student.setAge(15);
student.setName("張三");
student.setScore(90);
student.tell();
System.out.println("..............................");
System.out.println("name:"+student.getName()+";age:"+student.getAge()+";score:"+student.getScore());
}
}
class Person{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Student extends Person{
//private int age;
//private String name;
private int score;
//public int getAge() {
//return age;
//}
//public void setAge(int age) {
//this.age = age;
//}
//public String getName() {
//return name;
//}
//public void setName(String name) {
//this.name = name;
//}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public void tell(){
System.out.println("name:"+getName()+";age:"+getAge()+";score:"+getScore());
}
}
輸出結果:
name:張三;age:15;score:90
..............................
name:張三;age:15;score:90
2.1 在Java中只允許單繼承(一個子類只允許有一個父類),子類不能直接訪問父類的私有成員
示例2:
public class ExtendsDemo2 {
public static void main(String[] args){
PetWorker petWorker=new PetWorker();
petWorker.setAge(20);
petWorker.setWork("teacher");
petWorker.tell();
}
}
/**
* 創建類People
* @author Admin
*
*/
class People{
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/**
* 創建Worker類,單繼承People類
* @author Admin
*
*/
class Worker extends People{
private String work;
public String getWork() {
return work;
}
public void setWork(String work) {
this.work = work;
}
}
/**
* 創建PetWorker類,單繼承Worker類
* @author Admin
*
*/
class PetWorker extends Worker{
public void tell() {
System.out.println("age:"+getAge()+";work:"+getWork());
}
}
輸出結果:
age:20;work:teacher
2.2 Java方法重寫
定義:方法名稱相同,返回值類型相同,參數也相同,其實質就是子類定義了和父類同名的方法。
重寫限制:被子類重寫的方法不能擁有比父類方法更嚴格的訪問權限。private<default<public
子類調用父類中的方法:super.方法名(參數)
public class ExtendsDemo1 {
public static void main(String[] args) {
B b=new B();
b.tell();
}
}
class A{
public void tell(){
System.out.println("父類中的tell方法");
}
}
class B extends A{
public void tell() {
super.tell();
System.out.println("我重寫了tell方法");
}
void say(){
super.tell();
}
}
輸出結果:
父類中的tell方法
我重寫了tell方法
父類中的tell方法
2.3 抽象類與接口
final能申明類、方法和屬性,使用final申明的類不能被繼承,使用final申明的方法不能被重寫,使用final申明的變量變成常量(定義時要賦值),常量是不可以修改的。
抽象類:包含一個抽象方法的類就是抽象類。
定義:
abstract class ClassName{
屬性
方法
抽象方法
}
(1)抽象方法:申明而未實現的方法,抽象方法必須使用abstract關鍵字申明,只有方法名和參數,沒有方法體。
(2)抽象類被子類繼承,子類(若不是抽象類)必須重寫抽象類中的所有抽象方法。
(3)抽象類不能實例化,要通過其子類進行實例化。
public class AbstractClassDemo1 {
public static void main(String[] args) {
StuClass stuClass=new StuClass();
stuClass.tell();
stuClass.say();
}
}
abstract class AbsClass{
int age;
public void tell(){
System.out.println("父類中的tell方法");
}
public abstract void say();
}
class StuClass extends AbsClass{
@Override
public void say() {
System.out.println("子類實現父類抽象類中的say抽象方法");
}
}
接口可以理解為一種特殊的類(沒有構造方法),裡面全部是由全局常量和公共的抽象方法組成,接口的實現必須通過子類,使用關鍵字implements,而且子類可以多實現接口。一個接口不能實現(implements)另一個接口,但它可以繼承多個其它的接口。接口定義如下:
[修飾符] interface 接口名 [extends 父接口名列表]{
[public] [static] [final] 全局常量;
[public] [abstract] 抽象方法;
}
樣例:
public abstract class InterfaceDemo1 {
public static void main(String[] args) {
InterfaceClass interfaceClass=new InterfaceClass();
interfaceClass.print(1.0f);
}
}
class InterfaceClass implements CalInterface1,CalInterface2{
@Override
public void print(float r) {
System.out.println("半徑為"+r+"的圓面積:"+getArea(r)+",周長:"+getCircumference(r));
}
@Override
public float getArea(float r) {
float area=PI*r*r;
return area;
}
@Override
public float getCircumference(float r) {
float circumference=2*PI*r;
return circumference;
}
}
//定義接口CalInterface1
interface CalInterface1
{
float PI=3.14159f;//PI默認為public static final類型
float getArea(float r);//方法getArea()默認為public abstract類型,注意抽象方法沒有方法體
public abstract float getCircumference(float r);//計算面積
}
//定義接口CalInterface2
interface CalInterface2
{
void print(float r);//打印輸出結果
}
//定義接口CalInterface3,繼承接口CalInterface1和CalInterface2
interface CalInterface3 extends CalInterface1,CalInterface2{
}
輸出結果:
半徑為1.0的圓面積:3.14159,周長:6.28318
抽象類和接口的對比
(1)如果你擁有一些方法並且想讓它們中的一些有默認實現,那麼使用抽象類。
(2)如果你想實現多重繼承,那麼你必須使用接口。由於Java不支持多繼承,子類不能夠繼承多個類,但可以實現多個接口。因此你就可以使用接口來解決它。
(3)如果基本功能在不斷改變,那麼就需要使用抽象類。如果不斷改變基本功能並且使用接口,那麼就需要改變所有實現了該接口的類。