面向对象:
1.1类和对象
万物皆对象,包含:有形和无形的客观存在的事物或规律。
对象可以从两个方面表述:属性(数据模型)和行为(行为模型)。
对象是类的一个实例,有属性和行为。例如,一条狗是一个对象,它的属性有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
类是一个模板,它描述一类对象的属性和状态。
在 Java 编程中,我们使用成员变量表示数据模型,用成员方法表示行为模型。
一个类可以包含以下类型变量:
局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
类变量:类变量也声明在类中,方法体之外,但必须声明为 static 类型。一个类可以拥有多个方法比如狗的barking()、hungry()和sleeping()都是 Dog 类的方法。
1.3构造方法:
每个类都有构造方法如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法,构造方法一般是用于为成员属性赋初始化值。
在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。
1.4创建对象:
创建对象分为三步走
1 声明 :声明一个对象,包括对象的名称和对象的类型
2 实例化 :使用关键字new来创建
3.初始化: 使用new创建对象时,会调用构造方法初始化对象
2.1、局部变量
规则:
声明在构造方法、静态方法、实例方法、代码块中的变量,都是局部变量;
不能使用 static 和访问修饰符修饰;
可以使用 final 修饰,即为常量,不必在声明语句中赋值;
当执行局部变量所在的方法或代码块时,才有机会被创建,在方法或代码块执行结束后被自动销毁;
局部变量只在声明它的方法、构造方法或者语句块中可见;
局部变量在内存的栈区分配;
局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用;
2.2、实例变量
规则:
实例变量声明在一个类中,但在方法、构造方法和语句块之外,并且没有使用 static 修饰的变量,叫做实例变量;
当一个对象被实例化之后,每个实例变量的值就跟着确定;
可以使用访问修饰符和 final 修饰;
使用 final 修饰时,一定要赋值;
实例变量是在对象被创建时创建,对象被销毁时销毁;
实例变量对于类中的方法、构造方法或者语句块是可见的,作用域范围在整个类中;
一般情况下应该把实例变量设为私有;
实例变量具有默认值。数值型变量的默认值是 0,布尔型变量的默认值是 false,引用类型变量的默认值是 null;
变量的值可以在声明时指定,也可以在构造方法中指定;
2.3、静态变量
规则:
类变量也称为静态变量,在类中以 static 关键字声明,但必须声明在所有方法体和代码块之外,并且使用 static 修饰;
无论一个类创建了多少个对象,类只拥有类变量的一份拷贝;
可以使用访问修饰符修饰;
静态变量除了被声明为常量外很少使用,一般配合 final 使用,即 publicstatic fianl,标识符使用大写;
静态变量储存在静态存储区;
类变量被分配在静态存储区,是被所有该类的对象共享数据;
静态变量在第一次被访问时创建,在程序结束时销毁;
但为了对类的使用者可见,大多数静态变量声明为 public 类型;
默认值和实例变量相似。数值型变量默认值是 0,布尔型默认值是 false,引用类型默认值是 null;
变量的值可以在声明的时候指定,也可以在构造方法中指定,静态变量还可以在静态语句块中初始化。
静态变量可以通过:ClassName.VariableName 的方式访问,即类名.静态变量名;
3.1封装的概念
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。
封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
要访问该类的代码和数据,必须通过严格的接口控制。
适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。
3.2封装的优点
良好的封装能够减少耦合
类内部的结构可以自由更改
可以对成员变量进行更加准确的控制
隐藏信息 实现细节
3.3封装的步骤
声明(private)的属性
声明公开的(public)geter和seter方法
private String name;
private int birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setBirthday(int birthday) {
this.birthday = birthday;
}
public int getBirthday() {
return birthday;
}
4.1继承
继承就是子类继承父类的属性和行为,使得子类对象具有父类的实例和方法,子类从父类继承方法,使得子类具有父类相同的行为。
继承的优点:
当多个类中的代码存在重复了,导致后果就是代码量大且臃肿,而且维护性不高(维护性主要是后期需要修改的时候,就需要修改很多的代码,容易出错)
缺点:继承的缺点就是提高了类之间的耦合性,耦合度高就会造成代码之间的联系越紧密,代码独立性越差。
继承的关键字规则:
继承可以使用 extends 和 implements 这两个关键字来实现继承。
所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承 object(这个类在 java.lang 包中,所以不需要import)祖先类。
类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以extends 只能继承一个类。
使用 implements 关键字可以变相的使 java 具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。
super 关键字实现对父类成员的访问,用来引用当前对象的父类。
this 关键字是指向自己的引用。
final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写。
构造器继承规则:
子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。
如果父类的构造器带有参数,则必须在子类的构造器中显式地通过super 关键字调用父类的构造器并配以适当的参数列表。
如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。
实例化子类对象的步骤:先执行父类的构造方法,再执行子类的构造方法。
重写规则:
子类重新声明从父类继承来的方法,称为方法重写。
方法重写时,方法的声明部分要和父类保持一致(返回值类型,方法名,参数)。
重写方法的访问权限要大于等于父类中方法的访问权限。
子类重写父类方法,子类对象调用的是子类中重写后的方法。
使用 static 修饰的方法不能被重写,但是可以被子类重写声明。
不同包的子类可以重写父类中 protected 修饰的方法,但是不能以继承的形式,用子类对象直接调用父类的该方法。
耦合性
概念:
耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。耦合的强弱
取决于模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。模
块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关
系。模块间联系越多,其耦合性越强,同时表明其独立性越差( 降低耦合性,可
以提高其独立性)。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的
标准。划分模块的一个准则就是高内聚低耦合。
10.1、成员内部类
成员内部类声明在类中,方法体、代码块之外。和成员变量、成员方法在同
一级别。
在成员内部类中能访问外部类中所有静态成员 非静态成员 但不可以定义静态方法和静态成员变量
语法:
public class Out {
//成员内部类
public class Inner{
}
}
实例化成员内部类:
//先实例化外部类
Out o = new Out();
//使用外部类对象,再实例化内部
Out.Inner inner = o.new Inner()
实例
public class A {
private int n=100;//属性
public static int num=100;
//成员的方法
public void fn() {
System.out.println(n);
}
//成员的内部类。当成属性来看
class Inner{
private int n=1000;
private void fn() {
// TODO Auto-generated method stub
System.out.println("Inner的n="+n);
//System.out.println("A的n="+new A().n);//OK
//System.out.println("A的n="+this.n);//ERROR
System.out.println("A的n="+A.this.n);
}
}
public static void main(String[] args) {
A a=new A();
Inner in=a.new Inner();
//System.out.println(a.n);
System.out.println(in.n);
in.fn();
}
}
运行结果:
静态内部类
声明的位置参考成员内部类。
语法:
public class Out {
//静态内部类
public static class Inner{
}
}
实例化静态内部的对象:
Out.Inner inner = new Out.Inner();
public class Outer {
static int n=100;
private String name="张三";
private static void m(){
System.out.println("Outer的静态方法m...");
}
static class Inner{
public void fn() {
System.out.println(Outer.n);//OK
//System.out.println(name);不可以
Outer.m();//OK
}
public static void m() {
System.out.println("Inner的静态方法m...");
}
}
//成员内部类
class Inner2{
public void fn() {
System.out.println(Outer.n);
System.out.println(Outer.this.name);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(Outer.n);
Inner in=new Inner();//成功了
Inner2 in2=new Outer().new Inner2();//语法不同
in.fn();
in.m();
in2.fn();
}
}
在静态内部类中只能访问外部类静态成员 可以定义静态方法
10.3、局部内部类
声明在方法体或代码块内,作用域范围在方法体或代码块内。
public class Out {
public void method(){
//局部内部类
class Inner{
//局部内部类的成员方法
public void print(){
System.out.println("局部内部类");
}
}
//实例化局部内部类
Inner inner = new Inner();
inner.print();
}
}
必须清楚局部内部类,一定是在方法里面
局部内部类,如果想使用局部变量,前面一定要用final修饰,原因:保持语义的一致性
实例:
public static void main(String[] args) {
final int n=10;
class Inner{
public void fn()
{
System.out.println("n="+n);
}
}
Inner in = new Inner();
in.fn();
}
结果:10
匿名内部类:
声明位置同局部内部类一样,前提条件:必须继承一个类或实现一个接口,匿名内部类的声明和实例化对象是同时进行的;
一般使用于获得抽象类或接口对象;
1.匿名内部类 也是一种局部的内部类 没有名字
2.继承于抽象类 也可以实现接口(换句话说就是 可以抽象类的子类,也可以是接口的实现类)
public class Out {
public void method(){
//匿名内部类对象
Father f = new Father(){
};
}
}
abstract class A {
A() {
}
public abstract void m();
}
interface MyInterface{
public void fn();
}
public class Test {
public static void main(String[] args) {
//A a=new A();不行
/*
//这个地方想象一下创建了一个没有名字的类,这个类继承了抽象类A,实现了m()抽象方法。
A a=new A()
{
@Override
public void m() {
// TODO Auto-generated method stub
System.out.println("实现了m方法。。。");
}
};
a.m();
*/
/*
class MyClass extends A{
@Override
public void m() {
// TODO Auto-generated method stub
System.out.println("实现了m方法。。。");
}
}
A a=new MyClass();
a.m();
*/
/*
MyInterface my=new MyInterface() {
@Override
public void fn() {
// TODO Auto-generated method stub
System.out.println("实现了fn()....");
}
};
my.fn();
*/
class MyClass implements MyInterface{
@Override
public void fn() {
// TODO Auto-generated method stub
System.out.println("实现了fn()....");
}
}
MyInterface my=new MyClass();
my.fn();
}
}