您的位置:首页 > 编程语言

代码块、super关键字、方法重写、多态、抽象类、接口、内部类、匿名内部类、选择排序

2020-08-01 11:38 148 查看

代码块

1.局部代码块:在方法定义中用{}括起来的内容
作用:限定局部变量的生命周期。
2.构造代码块:在类中的成员位置定义的{}
作用:执行构造方法之前先执行构造代码块,然后对当前数据(类中的成员变量)进行初始化,将构造方法中的共性内容存储到构造代码块中。(一般情况都是通过构造方法初始化)
3.静态代码块:在类中的成员位置定义的static修饰的{}中的内容
作用:随着类的加载而加载,在{}里面给数据进行初始化,整个{}优先于对象存在,而且静态代码块只执行一次,因为类就加载一次。
例:看程序写结果

package com.qianfeng_01;

class A{
int i = 100;
public static void num() {
int j = 200;
System.out.println(j);
}
{
System.out.println(i);
}
public void num1() {
System.out.println(i);
}
}
class B extends A{
int x = 300;
public void num2() {
System.out.println(x);
}
{
System.out.println(x);
}
public static void num3() {
int k = 400;
System.out.println(k);
}
}

public class NumTest {

public static void main(String[] args) {
A a = new B();
B b = (B)a;
b.num();
b.num1();
b.num2();
b.num3();
}

}

继承(关键字:expends)

1.概念:将多个类中的共性内容抽取出来,放在另一个独立的类中,让这个独立的类(父类/超类)和其他类(子类/派生类)产生一种关系,这种关系称为继承。
2.格式: class 子类名 expends 父类名{}
3.好处:(1)提高了代码的复用性;
(2)提供了代码的维护性;
(3)类和类产生了这种“继承”关系。
4.继承的特点
在java语言中,类和类只支持单继承,不支持多继承,但支持多层继承。
例:

package com.qianfeng_01;
//测试类
public class AnimalTest {

public static void main(String[] args) {
// TODO Auto-generated method stub
Animal animal = new Dog("tom",3,"咖啡色");
System.out.println(animal.getName()+"\t"+animal.getAge()+"\t"+animal.getColor());
Dog dog = (Dog)animal;
dog.lookDoor();
AnimalTool.UserAnimal(new Dog());
animal = new Cat("baby",2,"黑色");
System.out.println(animal.getName()+"\t"+animal.getAge()+"\t"+animal.getColor());
System.out.println();
Cat cat = (Cat)animal;
cat.play();
AnimalTool.UserAnimal(new Cat());

}

}
package com.qianfeng_01;
//动物类  父类
public class Animal {

private String name;
private int age;
private String color;
public Animal() {
super();
// TODO Auto-generated constructor stub
}
public Animal(String name, int age, String color) {
super();
this.name = name;
this.age = age;
this.color = 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.println("动物吃饭");
}
public void sleep() {
System.out.println("动物睡觉……");
}
}
package com.qianfeng_01;
//子类  (猫类)
public class Cat extends Animal {

public Cat() {
super();
// TODO Auto-generated constructor stub
}

public Cat(String name, int age, String color) {
super(name, age, color);
// TODO Auto-generated constructor stub
}

public void eat() {
System.out.println("猫吃鱼……");
}
public void sleep() {
System.out.println("猫趴着睡……");
}
public void play() {
System.out.println("猫玩毛线……");
}
}
package com.qianfeng_01;
//子类(狗类)
public class Dog extends Animal {

public Dog() {
super();
// TODO Auto-generated constructor stub
}

public Dog(String name, int age, String color) {
super(name, age, color);
// TODO Auto-generated constructor stub
}

public void eat() {
System.out.println("狗吃骨头……");
}
public void sleep() {
System.out.println("狗卧着睡……");
}
public void lookDoor() {
System.out.println("狗看门……");
}
}
package com.qianfeng_01;
//工具类
public class AnimalTool {

public static void UserAnimal(Animal a) {
a.eat();
a.sleep();
}
}

super关键字

1.super:代表父类的空间标识(代表父类的对象的空间地址值引用)。
2.this和super的区别?
this:代表当前类对象的地址值引用
super:代表的父类的空间标识(父类对象的地址值引用)
this和super使用区别:
访问成员变量
this.成员变量名;访问本类的成员变量
super.成员变量名;访问的父类的成员变量
访问构造方法
this():访问的本类无参构造方法
super():访问父类的无参构造方法
this(xx):访问本类的有参构造方法
super(xx):访问父类的有参构造方法
访问成员方法
this.成员方法名();访问本类的成员方法
super.成员方法名();访问的父类的成员方法
3.super():如果在子类中的构造方法显示给出了,必须写在第一句,否则可能出现父类数据多次初始化。
4.继承中成员方法的关系
(1)子类继承父类,如果子类的成员方法和父类的成员方法不一致,只要通过子类对象分别调用即可。
(2)如果子类的成员方法和父类的成员方法一致:
1)先在子类成员位置找,如果有就使用;
2)如果没有,就在父类成员方法位置中找,如果有就使用;
3)如果没有,就报错,说明访问了一个不存在的变量。

方法重写(override)

1.概念:在继承关系中,子类出现了和父类一模一样的方法,这个时候,子类就会把父类的方法覆盖掉。这种现象称为方法重写。
例:猫狗案例

package com.qianfeng.doganli;
//测试类
public class DogGetAllTest {

public static void main(String[] args) {

Animal[] animals = new Animal[6];

//System.out.println(dog.name);
animals[0]= new Dog("tom");
animals[1]=new Cat("buyci");
animals[2]= new Dog("huage");
animals[3]=new Cat("banser");
animals[4]= new Dog("ran");
animals[5]=new Cat("mimi");

//程序用时
long startNano = System.nanoTime();

Dog[] as = DogGetAll(animals);

//遍历数组中的每一个元素
for(int i=0;i<as.length;i++) {
System.out.println(animals[i].getName());
}
System.out.println(System.nanoTime()-startNano);

}
/*
* 将一组动物中Dog的对象,挑选出来,并保存在一个Dog类型的数组中,并返回
*/
public static Dog[] DogGetAll(Animal[] animals) {
//1.定义计数器
int count=0;
int size=0;
//2.先数一遍,数组中有几只狗,再创建数组
for (int i = 0; i < animals.length; i++) {
//3.判断数组中每个元素,进行遍历
if (animals[i] instanceof Dog) {
//每发现一个Dog对象,计数器就增加一次
count++;
}
}
//4.根据计数结果创建合适的Dog数组
Dog[] dogs = new Dog[count];//时间(就是运行是的时间)和空间(资源)的平衡,效率与安全的平衡

//5.将animals所有的Dog对象保存在Dog对象中
for (int i = 0; i < animals.length; i++) {
//判断是否为Dog类型
if (animals[i] instanceof Dog) {
//将animals数组元素强转后,保存在数组中
dogs[size]=(Dog) animals[i];
//Dog数组的有效元素计数器自增
size++;
}
}
//将保存了所有的狗对象的数组,返回方法调用处
return dogs;
}
}
package com.qianfeng.doganli;
//动物类
public class Animal {

public String name;

public Animal() {
super();
// TODO Auto-generated constructor stub
}

public Animal(String name) {
super();
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
package com.qianfeng.doganli;

public class Cat extends Animal {

public Cat() {
super();
// TODO Auto-generated constructor stub
}

public Cat(String name) {
super(name);
// TODO Auto-generated constructor stub
}
}
package com.qianfeng.doganli;

public class Dog extends Animal {

public Dog() {
super();
// TODO Auto-generated constructor stub
}

public Dog(String name) {
super(name);
// TODO Auto-generated constructor stub
}
}

面试题

方法重写和方法重载的关系?
方法重载:方法名相同,参数列表不同,与返回值无关。
方法重写:方法名相同,参数列表相同。

多态

1.概念:一个事物在不同时刻的体现。
2.多态的前提条件:
(1)必须有继承关系
(2)方法重写,子类继承父类,将父类的功能覆盖掉,使用子类最具体的功能。
(3)父类引用指向子类对象。
3.多态成员方法实例化
向上转型:父类名 对象名 = new 子类名();
向下转型:子类名 对象名 = (子类名)父类对象名;

抽象类(关键字:abstract)

1.概念:在一个类中,如果该类中存在一个功能,仅仅声明方法,没有方法体(抽象方法),需要将该类定义为抽象类。
2.抽象类的特点:
1)如果一个类中有抽象方法,那么该类一定是抽象类;如果一个类是抽象类,那么该类中不一定有抽象方法。
2)抽象类不能实例化
3)抽象类需要通过子类进行实例化,父类引用指向子类对象。(抽象类多态)
3.格式:权限修饰符 abstract 返回值类型 方法名(形式参数){}
4.abstract和哪些关键字不能使用?
final 修饰的成员方法,不能重写,所以冲突了;
private 修饰的成员方法只能在本类中访问。
static 修饰的成员方法跟类有关,随着类的加载而加载,此时抽象方法没有方法体,加载进能存没有意义。
可以和public和protected权限修饰符使用。
例:定义一个抽象类student类和一个Demos类,Demos类中定义一个方法传入实体类参数。

package com.qianfeng.formal;

//参数为抽象类
abstract class Students{
public void study() {
System.out.println("爱学习,爱生活");
}
}

class Demos{
public void play(Students s) {
s.study();
}
}

//创建子抽象类
class Teacher extends Students{

@Override
public void study() {
System.out.println("Good Good study,Day Day up!");

}

}

//测试类
public class FormalTestDemo2 {

public static void main(String[] args) {
Demos demo = new Demos();
Students student = new Teacher();
student.study();

}

}

接口(关键字:interface)

1.概念:体现的是事物的一中扩展性功能。
2.接口中只能定义公开静态常量和公开抽象方法。
3.接口的成员特点是什么?
(1)成员方法:只能是抽象方法,存在默认修饰符,public abstract
(2)成员变量:只能是常量,存在默认修饰符,public static final
(3)构造方法:不存在构造方法。
例如:

interface MyInterface{
//公开静态常量
public static final String = "abc";
public  final String = "abc";
public static String = "abc";
String = "abc";
//公开抽象方法
public abstract void m1();
public void m2();
abstract void m3();
void m4();
}

4.抽象类和接口的区别?
(1)成员区别
成员变量:1)抽象类:既可以定义常量,也可以定义变量;
2)接口:只能定义常量,存在默认修饰符public static final
成员方法:1)抽象类:既可以定义抽象方法,也可以定义非抽象方法
2)接口:只能定义抽象方法,存在默认修饰符public abstract
构造方法:1)抽象类:存在构造方法,有参/无参,对数据进行初始化
2)接口:没有构造方法。
(2)关系区别:
类与类之间:不管这个类是抽象类还是具体类,都有继承关系;支持单继承,不支持多继承,但支持多层继承。
类于接口之间:Implements 一个类继承另一个类的同时,可以实现多个接口。
接口与接口之间:是继承关系,也可以多继承;提高代码的复用性,父接口中有的功能,子接口也具备该功能。
例`:

package com.qianfeng;

//定义一个接口
interface Inner{
void show();
}
class Outer1{
public static Inner method() {
//接口的匿名内部类,返回该接口的子实现类
return new Inner() {

@Override
public void show() {
System.out.println("helloword");
}
};
}
}
public class InnerfaceTest {
public static void main(String[] args) {
Outer1.method().show();//类名调用方法,说明该方法为一个静态
}
}

内部类

1.概念:就是在一个类中定义另一个类。
2.内部类可以访问外部类的成员,包括私有!
3.内部类的划分?局部内部类访问局部变量,JDK7以后在优化的时候自动为这个变量加上final,为什么?
解:分类:
成员内部类:在外部类的成员位置定义的类;
局部内部类:外部类成员方法中定义的类。
原因:局部变量的生命周期,随着方法调用而存在,随着方法调用完毕而消失,而当前这个局部变量被局部内部类在进行访问(局部内部类对象进行访问),在堆内存中对象不会被立即回收,它还在继续使用这个局部变量,需要将这个变量定义为常量,常驻内存---->以便局部内部类对象对该局部变量的访问!
4.需要访问静态成员内部类中的成员方法的访问方式!
外部类名.内部类名 对象名 = new 外部类名.内部类名();
对于内部类中的静态成员方法:
外部类名.内部类名.方法名();

package com.qianfeng_1;
/*
* 局部内部类
*/
//定义一个外部类
class Demo1{
//定义一个私有属性
private int i = 100;
static int j = 200;
public void method() {
class Demo2{
public void show() {
System.out.println(i);
System.out.println(j);
}
}
//创建内部对象
Demo2 demo2 = new Demo2();
demo2.show();
}
}

//测试类
public class InnerTestJubu {

public static void main(String[] args) {
//创建外部类的对象
Demo1 demo = new Demo1();
demo.method();
}
}

匿名内部类(一般在局部位置)

格式: new 类名/接口名(){
//方法重写;
};
本质:继承了该类或着实现了该接口的子类对象!

package com.qianfeng.day13night;
//定义一个接口
interface Inter{
public abstract void name();
}
//定义一个类
class Demo{
//定义一个私有属性
private String str = "abc";
public Inter method(Inter inter) {
System.out.println(str);
return inter;
}
}
//测试类
public class InterfaceTest {
public static void main(String[] args) {
Demo demo = new Demo();
Inter inter = demo.method(new Inter() {
@Override
public void name() {
System.out.println("爱学习");
}
});
inter.name();
}
}

选择排序

1.选择排序的思想:
使用0角标对应的数组元素依次和后面角标的元素进行比较,把小的往前放,第一次比较完毕,最小值就出现在了最小索引出,依次这样比较,可以得到排好序的数组!
2.总共比较次数=数组长度-1.

public class Array{
public static void main(String[] args){
int[] arr={12,25,3,14,26};
array(arr);
bianLi(arr);
}
public static void bianLi(int[] arr){
for(int i=0;i<arr.length;i++){
if(i==arr.length-1){
System.out.print(arr[i]+" ");
}else{
System.out.print(arr[i]+", ");
}
}
}
public static void array(int[] arr){
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[j]<arr[i]){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐