1—函数
函数是java 中最小的功能单元
函数也叫方法,作用是用于定义功能和封装代码。
– 函数有时候要多次使用某一块语句,就可以把这段语句提取出来,单独作为一个函数,使用时直接调用。提高代码复用性。主函数也是函数,是程序的入口,可以被JVM调用。
格式:修饰符 返回值类型 方法名 (参数类型 参数名,参数类型2,参数名2) { 方法体; return 返回值(void修饰时可以不写); }
1.如果函数的返回值类型是void,函数内就不需要写return语句,系统会自动加上。
2.如果返回值类型不是void,就需要return一个返回值,该返回值必须与函数上声明的返回值类型一样,否则编译失败。
3.函数中执行了return语句后,该函数就执行完毕,直接返回类型给调用者。方法的重载和重写:overload,override。
重载:方法名相同,参数列表不相同。
重写:方法名和参数列表都相同,重写之后前者被覆盖。举例: 调用函数打印乘法表。
class Demo
{
public static void main(String [] args)
{
chengfa(); //打印99乘法表。
chengfa(6); //打印66乘法表。
}
public static void chengfa (int num)
{
for (int x=1;x<=num;x++)
{
for (int y=1;y<=x;y++)
{
System.out.print(y+"*"+x+"="+y*x+"\t");
}
System.out.println();
}
}
public static void chengfa() //这里是重载函数。
{
chengfa(9); //调用带参数的函数。
}
}
—————————————————————————————————————————————-
面向对象三大特征:封装,继承,多态。
面向对象特点:
1.将复杂的事情简单化。
2.将程序从执行者变成了指挥者。
3.这种思想符合人们的思考习惯。
2—封装
封装就是隐藏对象的属性和细节,仅对外提供公共访问方式。
封装的好处:将变化隔离、便于使用、提高重用性、提高安全性。
private 关键字:将成员变量私有化,对外提供对应的set,get 方法对其访问。提高对数据访问的安全性。class Demo { private int age=10; public int getAge() { return age; } }
类中成员:
类就是对现实生活中事物的描述。
对象就是这类事物,是存在的个体。通过new操作符在堆内存中产生的实体。
在类中定义的都称之为成员。成员有两种:
—-成员变量:其实对应的就是事物的属性。
—-成员函数:其实对应的就是事物的行为。
属性对应类中的变量,行为对应类中的方法(函数);
定义类,就是在定义属性和行为 ; 属性和行为共同成为类中的成员。class Demo { public int age=10; //成员变量。 public void printAge() //成员函数。 { System.out.println("age="+age); } }
成员变量和局部变量的区别:
—-成员变量作用于整个类中。在堆内存中存在。有默认值,不赋值可以参与运算。
—-局部变量只作用于函数中或者语句中。在栈内存中存在。没有默认值,需要初始化之后才能参与运算。匿名对象:
new Car().num=5; //匿名对象。 Car c=new Car(); //命名对象,命名为c。
当对对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简便。
如果对一个对象的多个成员调用时,必须给这个对象起个名字。show(new Car());//中间的是匿名对象,匿名对象可以作为实际参数进行传递。
构造函数:函数名与类名相同。不用定义返回值类型。也不可以写return。
不写构造函数的类,系统会默认加一个空参数构造函数。
构造函数可以重载。
作用:给对象进行初始化动作。class Demo { Demo() { System.out.println("Demo"); } Demo(String name) { System.out.println(name); } public static void main(String [] args) { Demo d=new Demo(); //打印Demo。 Demo demo=new Demo("NAME"); //打印NAME。 } }
构造代码块:对象一建立就执行,优先于本类中的构造函数。给所有对象统一初始化。
class Demo { { System.out.println();//写在{ }中的语句是构造代码块。 } }
静态代码块:随着类的加载而执行。且只执行一次,并且优先于主函数执行。用于给类进行初始化。
class Demo { static { System.out.println(); //写在static { }中的语句叫静态代码块。 } }
区别:执行顺序优先级:静态代码块>构造代码块>构造函数。
即使书写顺序不同,也是按照这个顺序来执行。
每次调用构造函数时,都会先执行构造代码块再执行构造函数。
静态代码块随类的加载而执行,只执行一次。this:指的是本类中的,代表它所在函数所属对象的引用。
class Person { private String name; Person(String name) { //Person类中的name和自己传给Person构造方法的name不是同一个name,所以用this加以区分。 this.name=name; } } class Demo { public static void main(String [] args) { Person p=new Person("me"); } }
static:用于修饰成员。当成员被静态修饰后,除了可以被对象调用外,还可以直接被类名调用。
特点:
(1)随着类的加载而加载,随类的消失而消失。
(2)优先于对象存在。
(3)被所有对象共享。
(4)静态方法只能访问静态成员。
注意:
(1)静态方法只能够访问静态成员,非静态成员还没有在内存中建立。这是它的局限性。
(2)静态方法中不可以定义this,super 关键字。因为对象还不存在,this和super没有具体的指向对象。
(3)当功能内部没有访问到非静态数据时,该功能可以定义成静态的。
(4)静态的生命周期较长。成员变量和静态变量的区别:
1,成员变量所属于对象。所以也称为实例变量。
静态变量所属于类。所以也称为类变量。
2,成员变量存在于堆内存中。
静态变量存在于方法区中。
3,成员变量随着对象创建而存在。随着对象被回收而消失。
静态变量随着类的加载而存在。随着类的消失而消失。
4,成员变量只能被对象所调用 。
静态变量可以被对象调用,也可以被类名调用。
所以,成员变量可以称为对象的特有数据,静态变量称为对象的共享数据。
3—继承
一个类可以拿到父类的方法。
将多个类的共性提取出来,单独进行描述,然后让子类继承这个类,子类就有了共性类的特点。
继承的好处:提高了代码的复用性。java不支持多继承,因为会带来安全隐患:多个父类如果定义了相同的功能,且功能内容不同,子类对象不确定要运行哪一个。
java支持多重继承。A继承B B继承C C继承D。注意:
类与类之间有所属关系才可以使用继承。不能胡乱继承。
如果父类的属性都是子类应该有的,那么可以使用继承。如果父类的属性子类有不具备的,就不应该使用继承。
如果两个类没有包含关系,就不能直接使用继承。但是可以把相同的部分单独提取出来作为一个类。两个类都继承它。class Fu { static int age=10; } class Zi extends Fu { public static void main(String [] args) { System.out.println(age); } }
子父类中变量的特点:
加载子类时,会先加载父类。
子类中如果有非私有的同名成员变量时,访问本类变量用this.前缀;访问父类变量用super.前缀。
子类中如果有和父类一样的内容时,会把父类的内容替换掉。用于对父类中不需要的内容更改替换(覆盖,也叫重写)。注意:
覆盖时,子类权限必须要大于等于父类权限。否则编译失败。private权限最低。public权限最高。
如果父类中有private,这时子类访问不到,想要覆盖时,其实是新生成。
静态不能覆盖非静态,只能覆盖静态。子父类中构造函数的特点:
(1)子类构造函数第一行有隐式 super(); 会执行父类空参数构造函数。
(2)子类一定会访问父类的构造函数。因为子类对象在建立时,需要先查看父类有没有对数据初始化。
(3)如果要访问父类中指定的构造函数,可以手动定义super语句。
(4)如果父类中没有空参数构造函数,就必须手动输入 super 语句形式指定要访问的构造函数。
(5)父类的构造函数也有隐式super(); 继承上帝父类Object。
super()和 this()不可以同时出现的构造函数中。
//举例:
class Fu
{
static int num=2;
Fu()
{
System.out.println("Fu run");
}
Fu(String name)
{
System.out.println("Fu run "+name);
}
}
class Zi extends Fu
{
static int num=3;//覆盖了父类的成员变量。
Zi()
{
//super(); //这个是隐式的,调用的是父类的Fu();
System.out.println("Zi run");
}
Zi(String name)
{
//super(); //这里也有隐式语句调用父类对应构造函数。
System.out.println("Zi run "+name);
}
public static void main(String [] args)
{
Zi z=new Zi(); //子类空构造函数执行,打印父类的空构造函数中的语句和子类的语句。
Zi zz=new Zi("me"); //子类带参数构造函数执行,也是打印两个语句,先父后子。
System.out.println(num);
}
}
final 关键字:修饰符,可以修饰 类,函数,变量。
(1)final 修饰的类不可以被继承, final 修饰的函数不可以被覆盖, final 修饰的变量不可以被修改。
(2)继承的弊处在于打破了封装性,继承的覆盖功能可能改变原有函数的意义。final可以限制继承。
(3)写代码时,对于不会变的数据,尽量用final锁起来,即使数据只用一次,也需要这么做。final class Demo //类不能被继承。 { public static final double PI=3.14; //PI不能被修改。 public static final void method() //方法不能被覆盖。 { System.out.println(PI); } } }
抽象类: abstract 修饰符。
多个类中出现相同的功能,但功能主体不同。 这时就只抽取功能定义,不抽取功能主体。
抽象类的特点:
(1)抽象方法一定在抽象类中。方法和类都要被abstract修饰。
(2)抽象类不可以用new创建对象。因为调用抽象方法没意义。
(3)抽象类中的方法要被使用,必须由子类复写其所有的抽象方法后建立子类对象调用。
(4)如果子类只覆盖了部分抽象方法,该子类还是抽象类。注意:如果类中有抽象方法,那么该类就是抽象类。
//举例:工人和经理继承一个包含姓名,ID,工资的抽象类,复写抽象方法。经理特有奖金属性。
abstract class Person
{
private String name;
private int id;
private int pay;
Person (String name,int id,int pay)
{
this.name=name;
this.id=id;
this.pay=pay;
}
public abstract void work();
}
class GongRen extends Person
{
GongRen(String name,int id,int pay)
{
super(name,id,pay); //直接调用父类的构造函数中的内容。
}
public void work() //复写抽象方法。
{
System.out.println("工人工作。");
}
}
class JingLi extends Person
{
private int bonus; //经理特有的内容,需要私有化。
JingLi(String name,int id,int pay,int bonus)
{
super(name,id,pay);
this.bonus=bonus;
}
public void work()
{
System.out.println("经理工作!!");
}
}
class Demo
{
public static void main(String [] args)
{
GongRen g1=new GongRen("张三",1017,3000);
g1.work();
GongRen g2=new GongRen("李四",1617,3500);
g2.work();
JingLi j=new JingLi("王老五",26,5000,800);
j.work();
}
}
接口: interface 。
当抽象类中的方法都是抽象的,该类就可以通过接口的形式表示。 接口中的成员都是public的。
接口定义时的格式特点:
常量: public static final
方法: public abstract//形式
interface Inter { public static final int x=3; //修饰符可以不写,interface有常量固定格式,少写的会自动加上。 public abstract void show(); //修饰符也可以不写。 }
//简写形式:少写的会自动加上。
interface Inter { int x=3; void show(); } class Demo implements Inter { public void show(){} }
小知识点:
(1)类与类之间是继承关系。类与接口之间是实现关系:implements.
(2)父类中有非抽象内容可以直接拿过来用,这就是继承:extends。
而接口中全是抽象内容,子类要将接口中的内容实现后才能实例化。
(3)接口是不可以创建对象的。因为有抽象方法。
接口只有被子类implements实现,覆盖全部抽象方法后才可以实例化。否则子类是一个抽象类。
(4)接口可以被类多实现。注意:多实现的类要覆盖多个接口中的全部方法。
如果两个接口的方法名一致,只需要覆盖一次就行了。
一个类可以继承与实现共存。但是只能继承一个类,可以实现多个接口。
接口与接口可以多继承。
4—多态
多态指某一类事物的多种存在形态。
多态的前提:必须是类与类之间有关系,要么是extends,要么是implements。
必须是使用父类的引用访问父类中的成员。
多态的好处:多态提高了程序的扩展性。
多态写法体现:Fu f=new Zi(); //父类的引用指向了自己的子类对象。
在多态中成员函数的特点:静态与非静态的函数与变量,编译和运行都参考引用型变量所属的类中是否有调用方法。
只有一个特例,就是非静态成员函数在运行时参考”对象”所属的类中是否有调用方法。//举例:
class Fu { int num=5; void method1() { System.out.println("fu method1"); } void method2() { System.out.println("fu method2"); } } class Zi extends Fu { int num=6; void method1() { System.out.println("zi method1"); } void method3() { System.out.println("zi method3"); } } class Demo { public static void main(String[] args) { Zi z=new Zi(); z.method1(); //zi 1 z.method2(); //fu 2 z.method3(); //zi 3 Fu f=new Zi(); f.method1(); f.method2(); //f.method3(); //父类中没有method3方法。加上这句,编译不通过。 System.out.println(f.num); //5 System.out.println(z.num); //6 } }
内部类:定义在另一个类中的类。也叫内置类,嵌套类。
–特点:内部类可以直接访问其外部类的成员,包括私有成员。因为内部类持有外部类的引用。
外部类必须建立对象才能访问内部类。
格式:Outer.Inner in=new Outer().new Inner();
当事物内部还有事物时,内部事物就在使用外部事物的内容,就用内部类来描述。
静态内部类:在成员位置上的内部类可以被修饰符修饰,如 static 。
当内部类被static修饰后,只能直接访问外部类中的静态成员,有访问局限。
在外部其他类中,要想直接访问静态内部类中的非静态成员,直接new对象,如:new Outer.Inner().method();
要想直接访问静态内部类中的静态成员,直接类名调用。
Outer.Inner.function();
注意:
(1) 当内部类中定义了静态成员,该内部类必须是静态的。
(2) 外部类的静态方法访问内部类时,内部类也必须是静态的。
(3) 内部类定义在局部时,不可以被成员修饰符 static 修饰。匿名内部类:内部类的简写格式。就是一个匿名子类对象。
定义匿名内部类的前提:内部类必须是继承一个类或者实现一个接口。
匿名内部类中定义的方法最好是一两个。以简化书写。
//举例:interface Inter { void method(); } class Test { static Inter function() //接口类型 { return new Inter(){ public void method() { System.out.println("匿名内部类:run!"); } }; } } class Demo9 { public static void main(String [] args) { Test.function().method(); //可看成是 Inter in=Test.function(); in.method(); } }