|
一、代码块 代码块是使用{}定义的一段代码 代码块分为普通代码块、构造块、静态块和同步代码块 1.普通代码块 定义在方法中的代码块,若方法中代码较长,为避免变量重名,使用普通代码块进行分隔 2.构造块 定义在类中的代码块(不加修饰符) 注:构造块优先于构造方法执行,每产生一个新的对象就调用一次构造块,构造块可以进行简单的逻辑操作 3.静态代码块 使用static定义的代码块 (1)在非主类中的静态代码块 1)静态块优先于构造块执行。 2)无论产生多少实例化对象,静态块都只执行一次。 (2)在主类中的静态代码块 在主类中定义的静态块,优先于主方法(main)执行 class Person
{
{
System.out.println("1.类中的构造块");
}
public Person() {
System.out.println("2.类中的无参构造,代码块");
}
public Person(int i) {
System.out.println("3.类中的有参构造,代码块");
}
static {
System.out.println("4.类中的静态块");
}
}
public class Test {
{
System.out.println("5.主类中的代码块");
}
public Test() {
System.out.println("6.主类中的无参构造");
}
static
{
System.out.println("7.主类中的静态块");
}
public static void main(String[] args) {
System.out.println("————start————");
Test test1=new Test();
Test test2=new Test();
Person per1=new Person();
Person per2=new Person();
Person per3=new Person(2);
Person per4=new Person(3);
System.out.println("———— end ————");
}
}
上面这段代码执行的结果为 7.主类中的静态块 ————start———— 5.主类中的代码块 6.主类中的无参构造 5.主类中的代码块 6.主类中的无参构造 4.类中的静态块 1.类中的代码块 2.类中的无参构造,构造块 1.类中的代码块 2.类中的无参构造,构造块 1.类中的代码块 3.类中的有参构造,构造块 1.类中的代码块 3.类中的有参构造,构造块 ———— end ————
二、内部类
内部类的特点: (1)破坏了程序的结构 (2)方便进行私有属性的访问。(外部类也可以访问内部类的私有域) (3)如果发现类名称上出现了".",应当立即想到内部类的概念。 因此,内部类不作为设计的首选 内部类就是在一个类的内部进行其他类结构的嵌套的操作
class Outter
{
private String msg= "Hello World";
class Inner
{
public void print()
{
System.out.println(msg);
}
}
//需要在内部类外,外部类中定义一个方法,来将内部类进行实例化
public void fun()
{
Inner inner=new Inner();
inner.print();
}
}
public class Test
{
public static void main(String[] args)
{
Outter outter=new Outter();
outter.fun();
}
}
(1)如果想在程序外部调用,那么必须按照如下形式进行内部类的实例化对象创建 外部类.内部类 内部类对象 = new 外部类().new 内部类(); Outter.Inner in = new Outter().new Inner(); (2)如果说现在一个内部类只想被外部类使用,即:不希望直接产生内部类的实例化对象,可以使用private定义 (3)在进行属性访问时,都需要加上this关键字。所以如果想在内部类中明确的使用this,则格式为 外部类.this.属性 1.static定义内部类 内部类中如果使用了static进行定义。该内部类只允许访问外部类中的static操作。实际上该内部类等同于外部类,产生该内部类的实例化对象语法为 外部类.内部类 内部类对象 = new 外部类.内部类(); class Outter
{
private static String msg= "Hello World";
static class Inner
{
public void print()
{
System.out.println(msg);
}
}
public void fun() {
Inner inner=new Inner();
inner.print();
}
}
public class Test {
public static void main(String[] args) {
Outter.Inner inner=new Outter.Inner();
inner.print();
}
}
2.在方法中定义内部类(最常用)
class Outter
{
private String msg="Hello word";
public void fun() {
class Inner
{
public void print()
{
System.out.println(msg);
}
}
//在方法外部要将内部类进行实例化,并调用方法
Inner inner=new Inner();
inner.print();
}
}
public class Test {
public static void main(String[] args) {
Outter outter=new Outter();
outter.fun();
}
}
三、继承 面向对象的第二大特征:继承。
1)继承的主要作用在于,消除结构定义上的重复,在已有基础上继续进行功能的扩充,以及代码的重用。 2)子类对象的实例化流程:不管如何操作,一定要先实例化父类对象。 3)不允许多重继承,只允许多层继承。 1.继承的实现 继承使用extends关键字来实现,子类也称为派生类,父类也称为超类 class 子类 extends 父类 class Person
{
private String name;
private int age;
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;
}
}
class Student extends Person
{
private String sex;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
public class Test {
public static void main(String[] args) {
Student student=new Student();
student.setName("LLL");
student.setAge(11);
student.setSex("m");
System.out.println("name"+student.getName()+"age"+student.getAge()+"sex"+student.getSex());
}
} 当发生了类继承关系之后,子类可以直接继承父类的操作,可以实现代码的重用
2.继承的限制 (1)子类对象在进行实例化前一定会首先实例化父类对象。默认调用父类的构造方法后再调用子类构造方法 进行子类对象初始化 (2)如果父类里没有提供无参构造,那么这个时候就必须使用super()明确指明你要调用的父类构造 方法
class Person
{
public Person() {
System.out.println("1父类无参构造");
}
public void print() {
System.out.println("2父类的普通方法");
}
}
class Student extends Person
{
public Student() {
super.print();//指明了这个构造方法继承的是父类的print方法
//若此句不写,则student类就是一个普通类,就不是person类的子类
System.out.println("3子类的无参构造");
}
public Student(int i) {
System.out.println("4子类的有参构造");
}
public void fun()
{
super.print();
System.out.println("5子类的普通方法");
}
}
public class Test {
public static void main(String[] args) {
Student student1=new Student();//1 2 3
Student student2=new Student(1);//1 4
student1.fun();//2 5
}
}3.Java不允许多重继承,但是允许多层继承 (1)一个子类只能继承一个父类,C同时继承A和B的主要目的是同时拥有A和B中的操作,为了实现这样的目的,可以采用多层继承的形式完成 class A{} class B extends A{} class C extends B{}
(2)在进行继承的时候,子类会继承父类的所有结构。(包含私有属性、构造方法、普通方法)但是这个时候需要注意的是,所有的非私有操作属于显示继承(可以直接调用),所有的私有操作属于隐式继承(通过其他形式调用,例如setter或getter)
四、覆写 如果子类定义了与父类相同的方法或属性的时候,这样的操作就称为覆写1.方法的覆写 子类定义了与父类方法名称、参数类型及个数完全相同的方法称为覆写。但是被覆写不能够拥有比父类更为严格的访问控制权限。 (1)覆写的语句
class Person{
public void print()
{
System.out.println("1父类的普通方法");
}
}
class Student extends Person
{
public void print()
{
System.out.println("2子类对父类普通方法print的覆写");
}
}
public class Test
{
public static void main(String[] args)
{
Student student=new Student();//2
student.print();
}
}
1)只需要关注当前使用的对象是通过哪个类new的。 2)当调用某个方法,如果该方法已经被子类所覆写了,那么调用的一定是被覆写过的方法。 (2)覆写的权限 在进行方法覆写的时候,有明确的要求:被覆写不能够拥有比父类更为严格的访问控制权限。现在,见到的权限比较有private<default<public。那么也就意味着如果父类使用public进行方法声明,那么子类必须也使用public;如果父类使用default,那么子类可以使用default或者public。也就是说,覆写的子类方法的权限一定要大于等于被覆写的父类的方法权限。 注:父类使用private定义的方法,子类不能覆写
class Person
{
private void print()
{
//如果父类的方法是用private定义,则表示该方法只能被父类使用,子类无法覆写
System.out.println("2父类的普通方法");
}
}
class Student extends Person
{
public void print()
{
//此时只是在子类中重新定义了一个叫print的方法,根本没有对父类进行覆写
System.out.println("子类想要对父类普通方法print的覆写,结果覆写失败");
}
}
public class Test
{
public static void main(String[] args)
{
Student student=new Student();
student.print();
}
}(3)覆写与重载的区别 2.属性的覆写
当子类定义了和父类属性名称完全相同的属性的时候,就成为属性的覆盖
class Person
{
public String name="LLL";
}
class Student extends Person
{
public String name ="HHH";
}
public class Test
{
public static void main(String[] args)
{
Student student=new Student();
System.out.println("name"+student.name);
}
}
3.super关键字 (1)在继承时,子类调用父类构造方法时使用 (2)在进行覆写时使用 super.方法() 或者 super.属性 明确调用父类中的方法或属性
class Person
{
public String mString="父类属性";
public void print()
{
System.out.println("父类方法");
}
}
class Student extends Person
{
public String mString="子类属性";
public void print()
{
super.print();//在子类方法中调用父类方法
System.out.println(super.mString);//在子类方法中调用父类属性
System.out.println("子类方法");
System.out.println(this.mString);
}
}
public class Test
{
public static void main(String[] args)
{
Student student=new Student();
student.print();
}
}(3)this关键字和super关键字的区别 注:能使用super.方法()一定要明确标记出是父类的操作 (1)子类覆写父类的方法是因为父类的方法功能不足才需要覆写。 (2)方法覆写的时候使用的就是public权限
五、final关键字 在Java中final被称为终结器,可以使用final来定义类、方法、属性。 (1)使用final来定义类 使用final定义的类不能有子类(String类便是使用final定义) final class A{} //A类不能有子类 (2)使用final来定义方法 使用final定义的方法不能被子类所覆写。 class A{ public final void fun(){} } (3)使用final来定义属性 使用final定义的变量就成为了常量,常量必须在声明时赋值,并且不能够被修改。 publc final int LEVEL_A = 100 ;
六、多态性 1. 方法的多态性 (1)方法的重载:同一个方法名称可以根据参数的类型或个数不同调用不同的方法体 (2)方法的覆写:同一个父类的方法,可能根据实例化子类的不同也有不同的实现。 2. 对象的多态性【抽象类和接口才能体会到实际用处】(前提:方法覆写): 【自动,90%】①对象的向上转型:父类 父类对象 = 子类实例。 【强制,1%】②对象的向下转型:子类 子类对象 = (子类)父类实例。 (1)向上转型 class Person
{
public void print()
{
System.out.println("1.父类普通方法");
}
}
class Student extends Person
{
public void print()
{
System.out.println("2.子类普通方法对父类进行覆写");
}
}
public class Test {
public static void main(String[] args) {
Person person=new Student();//向上转型
person.print();
}
}
(2)向下转型 向下转型指的是将父类对象变为子类对象,当需要子类扩充操作的时候就要采用向下转型
class Person
{
public void print()
{
System.out.println("1.父类普通方法");
}
}
class Student extends Person
{
public void print()
{
System.out.println("2.子类普通方法对父类进行覆写");
}
public void fun()
{
System.out.println("子类特有的方法");
}
}
public class Test {
public static void main(String[] args) {
Person person=new Student();//向上转型(自动)
person.print();
Student student=(Student) person;//向下转型(强转)在向下转型之前,一定要进行向上转型
student.fun();
}
}
若向下转型具有安全隐患,则需要用instanceof关键字进行判断
public class Test {
public static void main(String[] args) {
Person person=new Student();//向上转型(自动)
person.print();
if(!(person instanceof Student ))
{
person =new Student();
Student student=(Student) person;
student.fun();
}
}
注: (1)对象多态性的核心在于方法的覆写。 (2)通过对象的向上转型可以实现接收参数的统一,向下转型可以实现子类扩充方法的调用 (2)两个没有关系的类对象是不能够进行转型的,一定会产生ClassCastException。
|